通過這種形式分配的,您可以通過分配指向其他數組的數組開始,像這樣:
T **a = malloc(sizeof *a * N); // N is the number of rows
sizeof *a
相當於sizeof (T *)
;數組中的每個元素將成爲指向T
的指針。當我們完成後,我們有一些像在內存中的以下內容:現在
+---+
a: | | a[0]
+---+
| | a[1]
+---+
| | a[2]
+---+
...
+---+
| | a[N-1]
+---+
,對於每一元素,我們分配另一的內存塊來保存T
類型的每個元素:
a[i] = malloc(sizeof *a[i] * M); // M is the number of columns
每個a[i]
的類型爲T *
,所以sizeof *a[i]
等於sizeof (T)
。
後這樣做了,我們有一些看起來像這樣的記憶:
+---+ +---------+---------+ +-----------+
a: | | a[0] ---> | a[0][0] | a[0][1] |...| a[0][M-1] |
+---+ +---------+---------+ +-----------+
| | a[1] ---> | a[1][0] | a[1][1] |...| a[1][M-1] |
+---+ +---------+---------+ +-----------+
| | a[2] ---> | a[2][0] | a[2][1] |...| a[2][M-1] |
+---+ +---------+---------+ +-----------+
...
+---+ +-----------+-----------+ +-------------+
| | a[N-1]--> | a[N-1][0] | a[N-1][1] |...| a[N-1][M-1] |
+---+ +-----------+-----------+ +-------------+
所以基本上你所做的是分配的T
N
單獨M
- 元素數組,然後你收集指針到N
-T *
的元素數組中的那些數組。
您可以像訪問任何普通的2D數組一樣訪問每個元素,如a[i][j]
;請記住,表達式a[i]
定義爲*(a + i)
;我們從a
中的地址抵消了i
元素(不是字節!),然後解除引用結果。所以a[i][j]
被評估爲*(*(a + i) + j)
。
所以,幾件事情與這種形式的分配的請記住:
陣列的「行」是不會在存儲器中連續;內存中的對象a[i][M-1]
(很有可能)不會是a[i+1][0]
。
由於每個「行」 a[i]
用呼叫分配給malloc
,還必須明確與之前free
相應的呼叫釋放取消分配a
(以相反的順序總是free
你malloc
)。
儘管我們可以將a
當作2D數組,但它沒有數組類型,所以您無法使用sizeof a
技巧來確定數組的大小;你只會得到指針類型的大小,而不是數組的總大小。所以你需要自己跟蹤數組的大小。
您可以隨時谷歌.. – wrangler
而且你可太consisten,你投了'的malloc()'第二次唯一不做它在所有或做它,即使它的醜陋和不必要的,但BE是一致的。 –
'for'循環非常小,嘗試使用小的具體值(比如說'm = n = 2')並且只是寫出函數的作用,擴展循環迭代。爲分配的塊和指針繪製方框和箭頭......如果您仍然無法看到發生了什麼,請解釋您所瞭解的位。 – Useless