allocazione dynamic / deallocazione di array 2D e 3D

Conosco algoritmi per allocare / deallocare un array 2D in modo dinamico, tuttavia non sono molto sicuro dello stesso per gli array 3D.
Usando questa conoscenza e un po ‘di simmetria, ho trovato il seguente codice.
(Ho avuto difficoltà a visualizzare in 3D durante la codifica).

Si prega di commentare la correttezza e suggerire qualsiasi alternativa migliore (in termini di efficienza o intuitivamente), se presente.
Inoltre, penso che entrambi questi array 2D e 3D siano accessibili normalmente come array statici come arr2D [2] [3] e
arr3D [2] [3] [2]. Destra?

Codice per 2D

//allocate a 2D array int** allocate2D(int rows,int cols) { int **arr2D; int i; arr2D = (int**)malloc(rows*sizeof(int*)); for(i=0;i<rows;i++) { arr2D[i] = (int*)malloc(cols*sizeof(int)); } } //deallocate a 2D array void deallocate2D(int** arr2D,int rows) { int i; for(i=0;i<rows;i++) { free(arr2D[i]); } free(arr2D); } 

Codice per 3D

 //allocate a 3D array int*** allocate3D(int l,int m,int n) { int ***arr3D; int i,j,k; arr3D = (int***)malloc(l * sizeof(int **)); for(i=0;i<l;i++) { arr3D[i] = (int**)malloc(m * sizeof(int*)); for(j=0;j<m;j++) { arr3D[i][j] = (int*)malloc(n*sizeof(int)); } } return arr3D; } //deallocate a 3D array void deallocate3D(int arr3D,int l,int m) { int i,j; for(i=0;i<l;i++) { for(int j=0;j<m;j++) { free(arr3D[i][j]); } free(arr3D[i]); } free(arr3D); } 

È inoltre ansible allocare un array e calcolare indici individuali. Ciò richiede un minor numero di chiamate allocator e risultati in termini di minore frammentazione e migliore utilizzo della cache.

 typedef struct { int a; int b; int* data; } Int2d; Int2d arr2d = { 2, 3 }; arr2d.data = malloc(arr2d.a * arr2d.b * sizeof *arr2d.data); 

Ora arr2d[r][c] diventa arr2d.data[r * arr2d.b + c] . La deallocazione è un singolo gratuito () di distanza. Come bonus sei sicuro di mantenere sempre le tue dimensioni di array dinamici con te.

Estrapolando al 3d:

 typedef struct { int a; int b; int c; int* data; } Int3d; Int3d arr3d = { 2, 3, 4 }; arr3d.data = malloc(arr3d.a * arr3d.b * arr3d.c * sizeof *arr3d.data); //arr3d[r][c][d] // becomes: arr3d.data[r * (arr3d.b * arr3d.c) + c * arr3d.c + d]; 

Dovresti incapsulare queste operazioni sugli indici (e le (de-) allocazioni per quella materia) in una funzione o macro separata.

(I nomi per r, c, e d potrebbero essere migliori: stavo andando per riga, colonna e profondità. Mentre a, b, e c sono i limiti delle loro dimensioni corrispondenti, potresti preferire qualcosa come n1, n2, n3 lì, o anche utilizzare un array per loro.)

arr3d dovrebbe essere un puntatore triplo e non solo un int. Altrimenti sembra OK:

 void deallocate3D(int*** arr3D,int l,int m) { int i,j; for(i=0;i 

arr3D è un pointer-to-pointer-to-pointer, quindi arr3D [i] è un puntatore-puntatore e arr3D [i] [j] solo un puntatore. È corretto rilasciare prima la dimensione più bassa in un ciclo, quindi risalire le dimensioni finché non viene rilasciato arr3D stesso.

Inoltre è più idiomatico dare a malloc la dimensione del tipo puntato implicitamente. Invece di:

  arr3D[i] = (int**)malloc(m * sizeof(int*)); 

Fallo:

  arr3D[i] = (int**)malloc(m * sizeof(*arr3D[i])); 

E sì, tali matrici multidimensionali allocate dynamicmente sono accessibili come array multidimensionali assegnati staticamente.

Puoi vedere il seguente codice:

 #include  #include  void main() { // Array 3 Dimensions int x = 4, y = 5, z = 6; // Array Iterators int i, j, k; // Allocate 3D Array int *allElements = malloc(x * y * z * sizeof(int)); int ***array3D = malloc(x * sizeof(int **)); for(i = 0; i < x; i++) { array3D[i] = malloc(y * sizeof(int *)); for(j = 0; j < y; j++) { array3D[i][j] = allElements + (i * y * z) + (j * z); } } // Access array elements for(i = 0; i < x; i++) { printf("%d\n", i); for(j = 0; j < y; j++) { printf("\n"); for(k = 0; k < z; k++) { array3D[i][j][k] = (i * y * z) + (j * z) + k; printf("\t%d", array3D[i][j][k]); } } printf("\n\n"); } // Deallocate 3D array free(allElements); for(i = 0; i < x; i++) { free(array3D[i]); } free (array3D); } 

Per maggiori dettagli vedi questo link 3d array

Questa è una versione dell’idea nella domanda, ma usando solo un malloc, ispirato alle altre risposte. Consente un uso intuitivo delle staffe quadre e una facile pulizia. Spero che non faccia alcuna ipotesi specifica per l’implementazione del compilatore.

 int main(int argc, char *argv[]) { int **array, i, j; array = allocate2d(3, 4); for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { array[i][j] = j + i + 1; } } for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) { printf("array[%d][%d] = %d\n", i, j, array[i][j]); } } free(array); return EXIT_SUCCESS; } int **allocate2d(int x, int y) { int i; int **array = malloc(sizeof(int *) * x + sizeof(int) * x * y); for (i = 0; i < x; i++) { array[i] = ((int *)(array + x)) + y * i; } return array; }