我正试图在堆上声明一个结构的三维数组。
假设我有以下结构:
struct data
{
double x;
double y;
};
我有:
typedef struct data data_t;
此外,尺寸如下:
int dim1, dim2, dim3;
我只是想不出一种方法来malloc一个三维结构数组
data_t ***arr;
arr = malloc(sizeof(*arr) * dim1);
for (int i = 0; i < dim1; i++) {
arr[i] = malloc(sizeof(*arr[i]) * dim2);
for (int j = 0; j < dim2; j++) {
arr[i][j] = malloc(sizeof(*arr[i][j]) * dim3);
}
}
使用循环进行内存分配。
data_t ***3d_arrOfStruct = malloc(dim1*sizeof(data_t **);
for(int i = 0; i < dim2; i++)
{
3d_arrOfStruct[i] = malloc(dim2*sizeof(data_t *);
for(int j = 0; i < dim2; j++)
{
3d_arrOfStruct[i][j] = malloc(dim3*sizeof(data_t);
}
}
请注意,这不会分配连续内存。
如果你的多维数组不是"锯齿状"的(正如你的问题所说的那样),那么由于C991,你只能简单地使用一个malloc
调用:
data_t (*p)[dim2][dim3] = malloc(dim1 * sizeof *p);
sizeof *p
已经"知道"每个子维度的大小,因此无需在右侧重复dim2
和dim3
。然而,如果你真的想重复你自己,那么等效的调用是:
data_t (*p)[dim2][dim3] = malloc(dim1 * dim2 * dim3 * sizeof p[0][0][0]);
甚至:
data_t (*p)[dim2][dim3] = malloc(dim1 * dim2 * dim3 * sizeof(data_t));
这种方法的另一个优点是,只需要一个free
调用就可以将其作为一个整体进行清理。
以下是可行的解决方案:
#include <stdio.h>
#include <stdlib.h>
struct data
{
double x;
double y;
};
typedef struct data data_t;
int main(void)
{
int dim1 = 1, dim2 = 2, dim3 = 3;
data_t (*p)[dim2][dim3] = malloc(dim1 * sizeof *p);
p[0][0][0].x = 0;
p[0][0][0].y = 0;
printf("%fn", p[0][0][0].x);
free(p);
return 0;
}
1)假设数组的大小在编译时未知。换句话说,它们不是常量表达式,但在您的问题中,dim1
、dim2
和dim3
被明确表示为变量
最简单、可能最快的方法是使用1d数组:
data* cube = (data*)malloc(dim1*dim2*dim3*sizeof(data));
data GetItem(int x, int y, int z)
{
auto index = x + y * dim1 + z * dim1 * dim2;
return cube[index];
}