使用三重指针将内存分配给3D数组
我必须使用三指针将内存分配给3D数组。
#include int main() { int m=10,n=20,p=30; char ***z; z = (char***) malloc(sizeof(char**)*m*n*p); return 0; }
这是正确的做法吗?(我认为我所做的是不正确的。)
要完全分配3D动态数组,您需要执行以下操作:
#include #include int main() { int m=10,n=20,p=30; char ***z; z = malloc(m * sizeof(char **)); assert(z != NULL); for (i = 0; i < m; ++i) { z[i] = malloc(n * sizeof(char *)); assert(z[i] != NULL); for (j = 0; j < n; ++j) { z[i][j] = malloc(p); assert(z[i][j] != NULL); } } return 0; }
释放数据留给读者练习。
没有必要在C中malloc()
的返回值。
如果你希望直接存储m * n * p
字符(并自己计算地址),那么你当然不应该按照char **
的大小来扩展分配。
你的意思是:
int m = 10, n = 20, p = 30; char *z = malloc(m * n * p * sizeof *z);
这将分配10 * 20 * 30 = 6000字节。 这可以被视为形成高度为p
的立方体,沿着垂直轴的每个“切片”是n * m
个字节。
由于这是用于手动寻址,您不能使用例如z[k][j][i]
来索引,而是必须使用z[k * n * m + j * m + i]
。
如果你不需要在一个连续的块中分配内存(通常情况下是IME),你可以这样做:
char ***z; z = malloc(sizeof *z * m); // allocate m elements of char ** if (z) { int i; for (i = 0; i < m; i++) { z[i] = malloc(sizeof *z[i] * n); // for each z[i], if (z[i]) // allocate n elements char * { int j; for (j = 0; j < n;j++) { z[i][j] = malloc(sizeof *z[i][j] * p); // for each z[i][j], if (z[i][j]) // allocate p elements of char { // initialize each of z[i][j][k] } } } } }
请注意,您需要以相反的顺序释放此内存:
for (i = 0; i < m; i++) { for (j = 0; j < n; j++) free(z[i][j]; free(z[i]); } free(z);
如果你真的需要在一个连续的块中分配内存,你有几个选择。 您可以分配单个块并手动计算偏移量:
char *z = malloc(sizeof *z * m * n * p); // note type of z! ... z[i * m + j * n + k] = some_value();
当你完成后,你只需要做一次free
:
free(z);
如果您有支持可变长度数组的C99编译器或C11编译器,您可以执行以下操作:
int m=..., n=..., p=...; char (*z)[n][p] = malloc(sizeof *z * m);
这将z
声明为指向n
x p
char
数组的指针,并且我们分配m
这样的元素。 内存是连续分配的,您可以使用普通的3-d数组索引语法( z[i][j][k]
)。 与上述方法一样,您只需要一个free
通话:
free(z);
如果您没有支持VLA的C99编译器或C11编译器,则需要生成n
和p
编译时常量,例如
#define n 20 #define p 30
否则最后一个方法将无效。
编辑
在这种情况下, m
不需要是编译时常量,只需要n
和p
。
你需要以下嵌套循环 –
z = (char**)malloc(sizeof(char*) * m); for (int i = 0; i < m; ++i) { *(z + i) = (char*)malloc(sizeof(char*) * n); for (int j = 0; j < n; ++j) { *(*(z + i)) = (char)malloc(p); } }
可能不是完全准确的,但它应该是这些方面的东西。
你想要sizeof(char)
而不是sizeof(char**)
因为后者会给你一个指针的大小,在大多数现代系统中它将是4个字节而不是你期望的1个。