我需要使用三级指针为一个三维数组分配内存。
#include <stdio.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = (char***) malloc(sizeof(char**)*m*n*p);
return 0;
}
这是我这样做的正确方式吗? (我认为我所做的是错误的。)
我需要使用三级指针为一个三维数组分配内存。
#include <stdio.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = (char***) malloc(sizeof(char**)*m*n*p);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
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]
。
如果您不需要内存在单个连续块中分配(在我看来通常是这种情况),则可以采用以下方式:
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);
int m=..., n=..., p=...;
char (*z)[n][p] = malloc(sizeof *z * m);
z
为一个指向char
类型的n
xp
数组的指针,我们分配m
个这样的元素。内存是连续分配的,您可以使用正常的三维数组索引语法(z[i][j][k]
)。与上面的方法类似,您只需要一次free
调用即可。free(z);
如果您没有C99编译器或支持VLAs的C11编译器,您需要将n
和p
设置为编译时常量,例如:
#define n 20
#define p 30
m
不需要是编译时常量,只需要n
和p
。const
修饰的对象不是编译时常量,而这是C89对于数组维度所要求的。而C++在这方面有所不同。 - John Bodesizeof(char)
而不是 sizeof(char**)
,因为后者会给你一个指针的大小,在大多数现代系统上将会是4个字节,而不是你期望的1个字节。sizeof(char)
,因为根据定义,它等于1。 - Paul Rz = (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);
}
}
可能不是语法上准确的,但应该大致是这样的。
z[i]
而不是 *(z + i)
。 - John Bode