我在一次采访中被问到如何分配一个二维数组,下面是我的解决方案。
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
}
我认为我做得很好,但后来他要求我使用一个 malloc()
语句而不是两个。我不知道如何实现它。
任何人都可以建议我在单个 malloc()
中完成它的想法吗?
最佳答案
只需计算 nrows
行指针和实际数据所需的内存总量,将其全部加起来,然后执行一次调用:
int **array = malloc(nrows * sizeof *array + (nrows * (ncolumns * sizeof **array));
如果您认为这看起来太复杂,您可以将其拆分并通过命名大小表达式的不同术语使其有点 self 记录:
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
然后您需要遍历并初始化行指针,以便每一行的指针指向该特定行的第一个元素:
size_t i;
int * const data = array + nrows;
for(i = 0; i < nrows; i++)
array[i] = data + i * ncolumns;
请注意,生成的结构与您使用的结构略有不同,例如int array[nrows][ncolumns]
,因为我们有明确的行指针,这意味着对于像这样分配的数组,没有真正要求所有行都具有相同数量的列。
这也意味着像 array[2][3]
这样的访问与对实际二维数组的类似访问不同。在这种情况下,最里面的访问首先发生,array[2]
从 array
中的第 3 个元素读取指针。然后将该指针作为(列)数组的基础,我们在其中进行索引以获取第四个元素。
相反,对于类似的东西
int array2[4][3];
这是一个“打包”的正确二维数组,仅占用 12 个整数的空间,像 array[3][2]
这样的访问简单地分解为向基地址添加一个偏移量获取元素。
关于c - 我们如何使用一个 malloc 语句分配一个二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8740195/