Verwendung von malloc zur Zuordnung von mehrdimensionalen Arrays mit unterschiedlichen Zeilenlängen

Ich habe den folgenden C Code:

 int *a; size_t size = 2000*sizeof(int); a = (int *) malloc(size); 

das funktioniert gut. Aber wenn ich folgendes habe:

 char **b = malloc(2000*sizeof *b); 

wo jedes Element von b unterschiedliche Länge hat.

Wie ist es möglich, für b dasselbe zu tun wie für a ; Dh der folgende Code würde korrekt sein?

 char *c; size_t size = 2000*sizeof(char *); c = (char *) malloc(size); 

Zuerst müssen Sie Array von pointersn wie char **c = malloc( N * sizeof( char* )) zuweisen, dann jede Zeile mit einem separaten Aufruf an malloc zuweisen, wahrscheinlich in der Schleife:

 /* N is the number of rows */ /* note: c is char** */ if (( c = malloc( N*sizeof( char* ))) == NULL ) { /* error */ } for ( i = 0; i < N; i++ ) { /* x_i here is the size of given row, no need to * multiply by sizeof( char ), it's always 1 */ if (( c[i] = malloc( x_i )) == NULL ) { /* error */ } /* probably init the row here */ } /* access matrix elements: c[i] give you a pointer * to the row array, c[i][j] indexes an element */ c[i][j] = 'a'; 

Wenn Sie die Gesamtzahl der Elemente kennen (zB N*M ), können Sie dies in einer einzigen Zuweisung tun.

Die typische Form für die dynamische Zuordnung eines NxM-Arrays vom Typ T ist

 T **a = malloc(sizeof *a * N); if (a) { for (i = 0; i < N; i++) { a[i] = malloc(sizeof *a[i] * M); } } 

Wenn jedes Element des Arrays eine andere Länge hat, ersetzen Sie M durch die entsprechende Länge für dieses Element. beispielsweise

 T **a = malloc(sizeof *a * N); if (a) { for (i = 0; i < N; i++) { a[i] = malloc(sizeof *a[i] * length_for_this_element); } } 

Die äquivalente Speicherzuweisung für char a[10][20] wäre wie folgt.

 char **a; a=(char **) malloc(10*sizeof(char *)); for(i=0;i<10;i++) a[i]=(char *) malloc(20*sizeof(char)); 

Ich hoffe, dass das einfach zu verstehen ist.

Der andere Ansatz bestünde darin, einen zusammenhängenden Speicherblock zuzuordnen, der einen Kopfblock für pointers auf Zeilen sowie einen Körperblock zum Speichern tatsächlicher Daten in Zeilen umfasst. Dann markieren Sie einfach den Speicher, indem Sie den pointersn im Header pro Zeile Zeilenadressen im Hauptteil zuweisen. Es würde wie folgt aussehen:

 int** 2dAlloc(int rows, int* columns) { int header = rows * sizeof(int*); int body = 0; for(int i=0; i 

Der Vorteil dieses Ansatzes ist das elegante Freigeben von Speicher und die Möglichkeit, Array-artige Notation zu verwenden, um auf Elemente des resultierenden 2D-Arrays zuzugreifen.

Wenn jedes Element in b unterschiedliche Längen hat, müssen Sie Folgendes tun:

 int totalLength = 0; for_every_element_in_b { totalLength += length_of_this_b_in_bytes; } return (char **)malloc(totalLength); 

Ich denke, ein 2-Schritt-Ansatz ist am besten, weil c 2-d-Arrays sind nur und Array von Arrays. Der erste Schritt besteht darin, ein einzelnes Array zuzuordnen und dann durchzuordnen, indem Arrays für jede Spalte zugewiesen werden. Dieser Artikel gibt gute Details.

malloc wird nicht an bestimmten Grenzen zugewiesen, daher muss davon ausgegangen werden, dass es auf einer Bytegrenze zugewiesen wird.

Der zurückgegebene pointers kann dann nicht verwendet werden, wenn er in einen anderen Typ konvertiert wird, da der Zugriff auf diesen pointers wahrscheinlich eine Speicherzugriffsverletzung durch die CPU erzeugt und die Anwendung sofort heruntergefahren wird.

2D-Array Dynamische Speicherzuweisung

 int **a,i; // for any number of rows & columns this will work a = (int **)malloc(rows*sizeof(int *)); for(i=0;i