7.13 我該如何動態分配多維數組 ?

傳統的解決方案是分配一個指針數組, 然後把每個指針初始化為動態分配的 ``列"。 以下為 一個二維的例子:
    #include <stdlib.h>

	int **array1 = malloc(nrows * sizeof(int *));
	for(i = 0; i < nrows; i++)
	    array1[i] = malloc(ncolumns * sizeof(int));
當然, 在真實代碼中, 所有的 malloc 返回值都必須檢查。你也可以使用 sizeof(*array1)  和 sizeof(**array1) 代替 sizeof(int *) 和 sizeof(int)。

你可以讓數組的內容連續, 但在後來重新分配列的時候會比較困難, 得使用一點指針算術:

	int **array2 = malloc(nrows * sizeof(int *));
	array2[0] = malloc(nrows * ncolumns * sizeof(int));
	for(i = 1; i < nrows; i++)
	    array2[i] = array2[0] + i * ncolumns;
在兩種情況下, 動態數組的成員都可以用正常的數組下標 arrayx[i][j] 來訪問  (for 0 <= i <nrows 和 0 <= j <ncolumns)。

如果上述方案的兩次間接因為某種原因不能接受, 你還可以同一個單獨的動態分配 的一維數組來模擬二維數組:

    int *array3 = malloc(nrows * ncolumns * sizeof(int));

但是, 你現在必須手工計算下標, 用 array3[i * ncolumns + j] 訪問第 i, j 個成員。 使用宏可以隱藏顯示的計算, 但是調用它的時候要使用括號和逗號, 這看起來不太像 多維數組語法, 而且宏需要至少訪問一維。參見問題 6.16

另一種選擇是使用數組指針:

    int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));
但是這個語法變得可怕而且運行時最多只能確定一維。

當然, 使用這些技術, 你都必須記住在不用的時候釋放數組 (這可能需要多個步驟; 參見問題 7.20)。 而且你可能不能混用動態數組和傳統的靜態分配數組。 參見問題 6.17 和 6.15

最後, 在 C99 中你可以使用變長數組。

所有這些技術都可以延伸到三維或更多的維數。

參考資料: [C9X, Sec. 6.5.5.2]。

翻譯朱群英、孫雲, LaTeX2HTML 編譯 朱群英 (2005-06-23)