Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 << zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch für Linux, Unix und Windows
– 2., aktualisierte und erweiterte Auflage 2006
Buch: C von A bis Z

C von A bis Z
1.116 S., mit CD, Referenzkarte, 39,90 Euro
Galileo Computing
ISBN 3-89842-643-2
gp Kapitel 16 Dynamische Speicherverwaltung
  gp 16.1 Das Speicherkonzept
  gp 16.2 Speicheralloziierung mit malloc()
  gp 16.3 Die Mysterie von NULL
    gp 16.3.1 NULL für Fortgeschrittene
    gp 16.3.2 Was jetzt – NULL, 0 oder \0 ... ?
    gp 16.3.3 Zusammengefasst
  gp 16.4 Speicherreservierung und ihre Probleme
  gp 16.5 free() – Speicher wieder freigeben
  gp 16.6 Die Freispeicherverwaltung
    gp 16.6.1 Prozessinterne Freispeicherverwaltung
  gp 16.7 Dynamisches Array
  gp 16.8 Speicher dynamisch reservieren mit realloc und calloc
  gp 16.9 Speicher vom Stack anfordern mit alloca (nicht ANSI C)
  gp 16.10 free – Speicher wieder freigeben
  gp 16.11 Zweidimensionale dynamische Arrays
  gp 16.12 Wenn die Speicheralloziierung fehlschlägt
    gp 16.12.1 Speicheranforderung reduzieren
    gp 16.12.2 Speicheranforderungen aufteilen
    gp 16.12.3 Einen Puffer konstanter Größe verwenden
    gp 16.12.4 Zwischenspeichern auf Festplatte vor der Alloziierung
    gp 16.12.5 Nur so viel Speicher anfordern wie nötig


Galileo Computing - Zum Seitenanfang

16.11 Zweidimensionale dynamische Arrays  toptop

In Abschnitt 14.9 haben Sie gelesen, dass das Anwendungsgebiet von Zeigern auf Zeiger unter anderem das dynamische Erstellen von Matrizen ist. Ich will Ihnen jetzt aber nicht die Suppe versalzen und als Thema die Matrizenberechnung nehmen, sondern ich werde nur einfache Speicherreservierungen mit Zeilen und Spalten vornehmen:

int matrix[zeile][spalte];

Um also für ein zweidimensionales Array mit beliebig vielen Zeilen und Spalten Speicher zu reservieren, benötigen Sie zuerst Platz für die Zeile. Und für jede dieser Zeilen wird nochmals Platz für die Spalte benötigt. Beim Freigeben des Speichers muss dies in umgekehrter Reihenfolge vorgenommen werden.

Hierzu das vollständige Listing:

/* 2D_dyn_array.c */
#include <stdio.h>
#include <stdlib.h>
#define BUF 255
int main(void) {
   int i, j, zeile, spalte;
   /* Matrix ist Zeiger auf int-Zeiger */
   int ** matrix;
   printf("Wie viele Zeilen : ");
   scanf("%d", &zeile);
   printf("Wie viele Spalten: ");
   scanf("%d", &spalte);
   /* Speicher reservieren für die int-Zeiger (=zeile) */
   matrix = (int **)malloc(zeile * sizeof(int *));
   if(NULL == matrix) {
      printf("Kein Virtueller RAM mehr vorhanden ... !");
      return EXIT_FAILURE;
   }
   /* Jetzt noch Speicher reservieren für die einzelnen Spalten
    * der i-ten Zeile */
   for(i = 0; i < zeile; i++) {
      matrix[i] = (int *)malloc(spalte * sizeof(int));
         if(NULL == matrix[i]) {
            printf("Kein Speicher mehr fuer Zeile %d\n",i);
            return EXIT_FAILURE;
         }
   }
   /* Mit beliebigen Werten initialisieren */
   for (i = 0; i < zeile; i++)
      for (j = 0; j < spalte; j++)
         matrix[i][j] = i + j;      /* matrix[zeile][spalte] */
   /* Inhalt der Matrix entsprechend ausgeben */
   for (i = 0; i < zeile; i++) {
      for (j = 0; j < spalte; j++)
         printf("%d ",matrix[i][j]);
      printf("\n");
   }
   /* Speicherplatz wieder freigeben
    * Wichtig! In umgekehrter Reihenfolge */
   /* Spalten der i-ten Zeile freigeben */
   for(i = 0; i < zeile; i++)
      free(matrix[i]);
   /* Jetzt können die leeren Zeilen freigegeben werden */
   free(matrix);
   return EXIT_SUCCESS;
}

Zugegeben, das Listing hat es in sich. Für einige dürfte es etwas undurchsichtig erscheinen, wie aus **matrix nun matrix[zeile][spalte] wird. Am besten sehen Sie sich einfach einmal an, was bei folgender Speicherreservierung geschehen ist:

matrix = (int **)malloc(zeile * sizeof(int));

Als Beispiel soll eine Matrix 4 × 3 erstellt werden, also vier Zeilen und drei Spalten.

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 16.9   Reservierung des Speichers für die Zeile (erste Dimension)

Nachdem Sie den Speicher für die einzelnen Zeilen reserviert haben, können Sie als Nächstes Speicher für die einzelnen Spalten reservieren.

   for(i = 0; i < zeile; i++) {
      matrix[i] = (int *)malloc(spalte * sizeof(int));
         if(NULL == matrix[i]) {
            printf("Kein Speicher mehr fuer Zeile %d\n",i);
            return EXIT_FAILURE;
         }
   }

Somit ergibt sich im Speicher dann folgendes finale Bild:

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 16.10   Nach der Reservierung des Speichers für die Spalte

Sicherlich erinnern Sie sich noch an die Demonstration des gleichwertigen Zugriffs auf ein Speicherobjekt mithilfe eines Zeigers und eines Arrays in Kapitel 14, Zeiger (Pointer). Auch bei den Zeigern auf Zeiger und den zweidimensionalen Arrays gibt es einige äquivalente Fälle. Hierzu eine Tabelle:


Tabelle 16.2   Äquivalenz zwischen Zeigern auf Zeiger und mehrdim. Arrays

Zugriff auf … Möglichkeit 1 Möglichkeit 2 Möglichkeit 3
1. Zeile, 1. Spalte **matrix *matrix[0] matrix[0][0]
i. Zeile, 1. Spalte **(matrix+i) *matrix[i] matrix[i][0]
1. Zeile, i. Spalte *(*matrix+i) *(matrix[0]+i) matrix[0][i]
i. Zeile, j. Spalte *(*(matrix+i)+j) *(matrix[i]+j) matrix[i][j]

 << zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z
C von A bis Z
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-Programmierung


Zum Katalog: C/C++






 C/C++


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Reguläre Ausdrücke






 Reguläre Ausdrücke


Zum Katalog: Linux






 Linux


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2006
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de