在堆上分配一个大小不确定的多维数组,同时保持数组索引语法
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];
其中 x
、y
和 z
是 uint64_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
像这样简单地 malloc
ing 池:
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);
请注意,最外层的维度 2
是 malloc()
参数中的一个因素,其他维度是指针类型的一部分,并且 sizeof(*pool)
正确计算了一个 3D 切片的大小你的 4D 数组。
维度 x
、y
、z
do not 需要是编译时常量。他们可以通过函数参数、局部变量、结构成员等等。它们的值只需要在指针的声明中就可以知道。
这在 C99 之后的 C 中有效,但在任何标准的 C++ 中都无效。 C11 使此功能成为可选功能,以便更轻松地为新平台实现符合标准的编译器,但大型编译器套件提供对此功能的全面支持。
我正在写一些涉及体素的小东西,所以我有一个充满数据的 3d 数组,就像这样
typedef struct data{float m,vx,vy,vz;} data;
data pool[2][x][y][z];
data voronoi[26];
其中 x
、y
和 z
是 uint64_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
像这样简单地 malloc
ing 池:
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);
请注意,最外层的维度 2
是 malloc()
参数中的一个因素,其他维度是指针类型的一部分,并且 sizeof(*pool)
正确计算了一个 3D 切片的大小你的 4D 数组。
维度 x
、y
、z
do not 需要是编译时常量。他们可以通过函数参数、局部变量、结构成员等等。它们的值只需要在指针的声明中就可以知道。
这在 C99 之后的 C 中有效,但在任何标准的 C++ 中都无效。 C11 使此功能成为可选功能,以便更轻松地为新平台实现符合标准的编译器,但大型编译器套件提供对此功能的全面支持。