在堆上分配一个大小不确定的多维数组,同时保持数组索引语法

Allocate a multidimensional array of ungauranteed size on the heap while keeping array indexing syntax

我正在写一些涉及体素的小东西,所以我有一个充满数据的 3d 数组,就像这样

typedef struct data{float m,vx,vy,vz;} data;
data pool[2][x][y][z];
data voronoi[26];

其中 xyzuint64_t。但它们的实际值取决于运行时的用户输入。现在事实证明,当数组变得太大(甚至不能做 128x128x128)时,我会遇到分段错误,即使我有足够多的 RAM。所以我需要在堆上分配它。我该怎么做,同时也不需要像这样转换代码:

uint64_t h,b,d,p;
p = 0;
for(h=1;h<y-1;++h){
for(b=1;b<x-1;++b){
for(d=1;d<z-1;++d){
voronoi[ 0] = pool[p][h-1][b-1][d-1];
voronoi[ 1] = pool[p][h  ][b-1][d-1];
voronoi[ 2] = pool[p][h+1][b-1][d-1];
voronoi[ 3] = pool[p][h-1][b  ][d-1];
voronoi[ 4] = pool[p][h  ][b  ][d-1];
voronoi[ 5] = pool[p][h+1][b  ][d-1];
voronoi[ 6] = pool[p][h-1][b+1][d-1];
voronoi[ 7] = pool[p][h  ][b+1][d-1];
voronoi[ 8] = pool[p][h+1][b+1][d-1];
    //etc until 26

}}}
p = 1;
// repeat cycle, then p=0 again, etc

像这样简单地 mallocing 池:

data* pool=(2*x*y*z*sizeof(data));

这不是重复的,因为 malloc-ing 一个一维数组并添加自定义索引(goto 答案)会使多维方括号索引语法无效。

简单。使用指向多维数组的指针:

data (*pool)[x][y][z] = malloc(2*sizeof(*pool));
...
for(h=1;h<y-1;++h){
    for(b=1;b<x-1;++b){
        for(d=1;d<z-1;++d){
            voronoi[ 0] = pool[p][h-1][b-1][d-1];
            ...
}
...
free(pool);

请注意,最外层的维度 2malloc() 参数中的一个因素,其他维度是指针类型的一部分,并且 sizeof(*pool) 正确计算了一个 3D 切片的大小你的 4D 数组。

维度 xyz do not 需要是编译时常量。他们可以通过函数参数、局部变量、结构成员等等。它们的值只需要在指针的声明中就可以知道。

这在 C99 之后的 C 中有效,但在任何标准的 C++ 中都无效。 C11 使此功能成为可选功能,以便更轻松地为新平台实现符合标准的编译器,但大型编译器套件提供对此功能的全面支持。