通过这种形式分配的,您可以通过分配指向其他数组的数组开始,像这样:
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