使用指针为 C 中的 3D 数组分配内存?

allocating memory for a 3D array in C using pointers?

我在 C 中有以下代码:

double ***grid
grid = calloc(nx, sizeof(double**))
for (int i = 0; i < nx; ++i) {
    grid[i] = calloc(ny,sizeof(double*));
    for (int j = 0; j < ny; ++j) {
        grid[i][j] = calloc(nz,sizeof(double));
    }
}

我不明白的是为什么我们不能写grid[i]=calloc(ny,sizeof(double**))? grid的每个成员不都是一个"pointer to pointer"吗?我们不应该有 grid[i][j] = calloc(nz,sizeof(double*)) 吗?

当我以当前形式使用 grid[i][j][k] 时,代码工作正常,但我对原因感到困惑。我是 C 的新手,所以我很感激所有形式的解释。

编辑:缺少一行:grid = calloc(nx, sizeof(double**))

首先你错过了第一个 alloc: grid = calloc(nx, sizeof(double **)); 但我不确定这是关键,因为代码甚至没有编译(在 grid 声明后缺少分号所以它必须有被分配到别处)

然后回答你的问题,在对象上分配returns一个指针,这增加了一个额外的*,但是你必须指定元素的大小以便calloc进行计算(ny*sizeof(object))

grid[i]=calloc(ny,sizeof(double**))

可以,因为 double 指针上的指针大小与 double 指针相同,但并不完美。

如果你有一个像这样分配的 int 数组:

int *array = calloc(ny,sizeof(int *))

它在大多数平台上都可以正常工作,但是如果您使用的是带有标准 32 位 int 的 64 位架构(例如,windows 64 位框,gcc 64位编译器),因为指针是 64 位的,它会分配两倍于你真正需要的内存。这种情况下的正确语法是:

int *array = calloc(ny,sizeof(int))

因为元素是 int,它 returns 是 int (int *)

上的指针

所以,现在,当您在左侧添加一颗星时,您会在右侧添加一颗星:

int **array = calloc(ny,sizeof(int *))
int ***array = calloc(ny,sizeof(int **))

等等...

个人小故事:从 32 位迁移到 64 位时遇到了一些令人讨厌的崩溃,当时人们习惯使用:

int **array = calloc(ny,sizeof(int))   // WRONG!!

这在一切都是 32 位时有效。当 sizeof(int *) 由于 64 位 arch 而增加到 8 个字节时,只分配了一半的大小,这可能会导致非常有趣的错误。