2016-08-13 78 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

你是對的。編輯 –