2016-08-13 59 views
0

我在C下面的一段代码:使用指针为C中的3D数组分配内存?

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[i][j] = calloc(nz,sizeof(double*))

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

编辑:一条线是丢失:grid = calloc(nx, sizeof(double**))

+1

从一个简单的例子开始:'int * p; p = calloc(10,sizeof(int));' – melpomene

+0

@melpomene exellent suggestion,thanks :) – secluded

+1

标题误导:显示的代码分配了一个锯齿状的“3D-阵列”,实际上它是一维“双**,大小为X,X 1D,数组为double *,大小为Y,Y为1D,数组为double,大小为Z。所以这里只有一维数组,即1 + X + Y。一个真正的3D数组可以像这样定义'double array3d [X] [Y] [Z]'。 – alk

回答

1

首先你错过了第一页头:grid = calloc(nx, sizeof(double **));,但我不知道这是因为代码甚至不编译(缺少分号后grid声明,使点它必须被分配在其他地方)

然后回答你的问题,分配返回的对象,它增加了一个额外*上的指针,但你必须指定元素的大小释放calloc使计算(ny*sizeof(object))

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

会工作,因为double指针的指针大小与double指针的大小相同,但并不完美。

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

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

它将工作在大多数平台上的所有权利,但如果你是一个64位架构与标准的32位int (例如Windows 64位盒,gcc 64位编译器),因为指针是64位,它将分配两倍的内存,你真正需要。在这种情况下,正确的语法是:

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

,因为该元素是int,并返回上intint *

所以一个指针,现在,反复,当你在加入星左边,你加在右边的明星:

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

等等...

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

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

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

+0

“* double指针的指针大小与double *指针的大小相同” - 这在实际中通常是真实的,但不能保证为C. – melpomene

+0

int * array = calloc(ny,sizeof(int *))不能保证工作:'int'在理论上可能比'int *'大。 – melpomene

+0

你是对的。编辑 –