这个问题是参考此处提供的解决方案/解释Allocating variable length multi dimensional arrays(参见接受的答案)。
在我的情况下,我使用相同的功能来定义3D数组,如下面的
void arr_alloc (int x, int y, int z, int(**aptr)[x][y][z])
{
*aptr = malloc( sizeof(int[x][y][z]) ); // allocate a true 3D array
assert(*aptr != NULL);
}
对于我正在处理的代码库,这是一个巨大的项目存储库,早些时候我使用的指针指向指向类型(***数组)的指针,然后交错使我可以将它用作3D(伪)阵列。为此,我曾将变量声明为extern int ***array
,并将指针定义在单独的头文件中int ***array
。我的问题 - (a)对于新的函数,应该是数组的声明和定义,因为SO参考答案使用了声明和定义,例如
int x = 2;
int y = 3;
int (*aptr)[x][y];
(b)使用size_t
vs int
作为索引变量的激励,假设size_t
占用8个字节,而int
占用4个字节。
PS。我在gdb中检查了上面提到的声明和定义行之后的变量类型(也在SO答案中)(int (*)[variable length][variable length][variable length]) 0x0
编辑:请注意,这个问题是关于数组/数组指针的声明和定义,而不是分配和设置数组的函数的声明。
答案 0 :(得分:2)
函数声明对于分配3D数组是正确的。指向这样一个数组的指针将具有类型int (*)[a][b][c]
,因此该函数需要接受该类型的指针的地址以写入它,即int (**)[a][b][c]
,这就是你所拥有的。
要使用此功能,您需要按如下方式调用它:
int s1=2, s2=3, s3=4;
int (*p)[s1][s2][s3];
arr_alloc(s1,s2,s3,&p);
然后你可以像这样写入3D数组:
int i,j,k;
int n = 0;
int i,j,k;
int n = 0;
for (i=0;i<s1;i++) {
for (j=0;j<s2;j++) {
for (k=0;k<s3;k++) {
(*p)[i][j][k] = n++;
}
}
}
编辑:
真正的多维数组必须声明除第一个维度之外的所有维度的大小。如果您的数组是在文件范围声明的,那意味着这些维度的大小必须是编译时常量。
如果尺寸必须变化,则需要将其设为void *
并根据需要进行投射。你在这里放松了一些类型检查,但这是唯一的方法:
int s1, s2, s3;
void *arr;
void arr_alloc (int x, int y, int z)
{
int (*p)[x][y][z] = malloc( sizeof(int[x][y][z]) );
assert(p != NULL);
arr = p;
s1=x;
s2=y;
s3=z;
}
int main()
{
arr_alloc(2,3,4);
int (*p)[s1][s2][s3] = (int(*)[s1][s2][s3])arr;
int i,j,k;
int n = 0;
for (i=0;i<s1;i++) {
for (j=0;j<s2;j++) {
for (k=0;k<s3;k++) {
(*p)[i][j][k] = n++;
}
}
}
for (i=0;i<s1;i++) {
for (j=0;j<s2;j++) {
for (k=0;k<s3;k++) {
printf("%d:%d:%d=%d\n",i,j,k,(*p)[i][j][k]);
}
}
}
free(p);
return 0;
}