malloc 怎么知道它首先要分配一个指针数组,每个指针都指向一个一维数组?
它没有; malloc 只是分配您指定的字节数,它不知道如何将这些字节构造成聚合数据类型。
如果您尝试动态分配多维数组,您有多种选择。
如果您使用支持可变长度数组的 C99 或 C2011 编译器,您可以简单地将数组声明为
int rows;
int cols;
...
rows = ...;
cols = ...;
...
int array[rows][cols];
不过,VLA 存在许多问题;它们不适用于非常大的数组,它们不能在文件范围内声明,等等。
第二种方法是执行以下操作:
int rows;
int cols;
...
rows = ...;
cols = ...;
...
int (*arrayPtr)[cols] = malloc(sizeof *arrayPtr * rows);
在这种情况下,arrayPtr 被声明为指向带有 cols 元素的 int 数组的指针,因此我们将分配 rows 数组中的每个 cols 元素。请注意,您只需编写 arrayPtr[i][j] 即可访问每个元素;指针算术规则的工作方式与常规二维数组相同。
如果您使用的不是支持 VLA 的 C 编译器,则必须采用不同的方法。
您可以将所有内容分配为单个块,但您必须将其作为一维数组访问,计算偏移量如下:
int *arrayPtr = malloc(sizeof *arrayPtr * rows * cols);
...
arrayPtr[i * rows + j] = ...;
或者你可以分两步分配:
int **arrayPtr = malloc(sizeof *arrayPtr * rows);
if (arrayPtr)
{
int i;
for (i = 0; i < rows; i++)
{
arrayPtr[i] = malloc(sizeof *arrayPtr[i] * cols);
if (arrayPtr[i])
{
int j;
for (j = 0; j < cols; j++)
{
arrayPtr[i][j] = some_initial_value();
}
}
}
}