我在理解C如何为2D(或更多维)数组分配空间时遇到了问题,尤其是当我们使用malloc
之类的时候。以this question中的程序为例。
首先定义一维指针数组,然后将指向1D数据数组(在本例中为字符串)的指针放在第一个1D数组的每个框中。因此无法保证整个2D数组是连续的(前一行的最后一个单元后跟下一行的第一个单元)。每个1D数据阵列可以非常远,只有它们的指针是连续的。我纠正还是错过了什么?如果你能帮我澄清一下,我真的很感激。
答案 0 :(得分:6)
有多种方法可以实现,具体取决于您将如何访问它。您可以确保阵列的主体是连续的,或者您可以避免这种情况。对于字符串数组,通常不需要使数组的主体连续。对于整数或双精度的2D(等)数组,通常会使数组的主体连续。
在示例中,数组的数据类型是泛型类型T
,假定为数字,因此可以为数组元素分配0
。这些示例没有错误检查内存分配;他们应该在生产代码中。
int n1 = 5;
int n2 = 6;
T *a = malloc(n1 * n2 * sizeof(T));
for (int i = 0; i < n1; i++)
for (int j = 0; j < n2; j++)
a[i * n2 + j] = 0;
free(a);
int n1 = 5;
int n2 = 6;
T **a = malloc(n1 * sizeof(T*));
T *b = malloc(n1 * n2 * sizeof(T));
for (int i = 0; i < n1; i++)
a[i] = &b[i * n2];
for (int i = 0; i < n1; i++)
for (int j = 0; j < n2; j++)
a[i][j] = 0;
free(b);
free(a);
int n1 = 5;
int n2 = 6;
T **a = malloc(n1 * sizeof(T*));
for (int i = 0; i < n1; i++)
a[i] = malloc(n2 * sizeof(T));
for (int i = 0; i < n1; i++)
for (int j = 0; j < n2; j++)
a[i][j] = 0;
for (int i = 0; i < n1; i++)
free(a[i]);
free(a);
答案 1 :(得分:3)
你是对的,不能保证数据是连续的,事实上它很可能不会。顶级数组(行)只是一个指针数组(每个元素都是它自己的指针)。这些指针每个都指向它们自己的一维实际对象数组。这些缓冲区只能通过指针连接。
/* allocation */
int** array = malloc(sizeof(int*) * height)
for (int y = 0; y < height; y ++)
{
array[i] = malloc(sizeof(int) * width);
}
/* indexing */
int item = array[y][x];
分配2D数组的另一种方法是使用单个缓冲区,然后根据2D坐标对其进行索引。例如8 * 8 = 64.分配单个64字节缓冲区并且index = x + y * 8.此方法连续存储数据,并且比方法1更容易分配和解除分配。
/* allocation */
int* array = malloc(sizeof(int) * width * height)
/* indexing */
int item = array[x + y * width];
答案 2 :(得分:2)
我认为你是对的。但是如果你真的希望数组是连续的,你可以malloc
一维数组并像二维数组一样使用它,比如
int* oneDArray = (int*)malloc(sizeof(int)*10*10);
int a = oneDArray[i*10+j]; //which equals to twoDArray[i][j]