2D和3Darrays的动态分配/释放

我知道动态分配/解除分配2D数组的算法,但是对于3D数组我也不太清楚。
利用这些知识和一点对称性,我想出了以下代码。
(我在编码期间很难在3D中进行可视化)。

请评论正确性并建议任何更好的替代方案(效率方面或直观方面),如果有的话。
此外,我认为这些2D和3D数组都可以正常访问,如静态数组,如arr2D [2] [3]和
arr3D [2] [3] [2]。 对?

二维码

//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); } 

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); } 

您还可以分配一个数组并计算单个索引。 这需要更少的分配器调用,并导致更少的碎片和更好的缓存使用。

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

现在arr2d[r][c]变成了arr2d.data[r * arr2d.b + c] 。 解除分配是一个免费的()。 作为奖励,您一定要始终保持动态arrays大小。

外推到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]; 

您应该在单独的函数或宏中封装这些索引操作(以及(de)分配)。

(r,c和d的名称可能更好 – 我选择行,列和深度。虽然a,b和c是相应尺寸的限制,但您可能更喜欢n1,n2,n3之类的东西在那里,甚至为他们使用数组。)

arr3d应该是一个三指针而不仅仅是一个int。 否则看起来不错:

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

arr3D是一个指向指针的指针,因此arr3D [i]是一个指向指针的指针而arr3D [i] [j]只是一个指针。 首先在循环中释放最低尺寸是正确的,然后爬上尺寸直到arr3D本身被释放。

另外,为malloc提供隐式的指向类型的sizeof也更为惯用。 代替:

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

做了:

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

是的,这种动态分配的多维数组可以像静态分配的多维数组一样被访问。

您可以看到以下代码:

 #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); } 

有关详细信息,请参阅此链接3d数组

这是该问题的一个版本,但只使用一个malloc,灵感来自其他答案。 它允许直观地使用方括号并易于清洁。 我希望它不会使任何编译器实现特定的假设。

 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; }