使用指针为 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 个字节时,只分配了一半的大小,这可能会导致非常有趣的错误。
我在 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 个字节时,只分配了一半的大小,这可能会导致非常有趣的错误。