在使用malloc时,C如何为2D(3D …)数组分配空间?

我在理解C如何为2D(或更多维)数组分配空间时遇到问题,尤其是当我们使用malloc等时。 以这个问题中的程序为例。

首先定义一维指针数组,然后将指向1D数据数组(在这种情况下为字符串)的指针放在第一个1D数组的每个框中。 因此无法保证整个2D数组是连续的(前一行的最后一个单元后跟下一行的第一个单元)。 每个1D数据arrays可以非常远,只有它们的指针是连续的。 我纠正还是错过了什么? 如果你能帮助我澄清这一点,我将非常感激。

有多种方法可以实现,具体取决于您将如何访问它。 您可以确保数组的主体是连续的,或者您可以避免这种情况。 对于字符串数组,通常不需要使数组的主体连续。 对于整数或双精度的2D(等)数组,通常会使数组的主体连续。

在示例中,数组的数据类型是generics类型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(缓冲区指针,非连续)

你是对的,不能保证数据是连续的,事实上它很可能不会。 顶级数组(行)只是一个指针数组(每个元素都是它自己的指针)。 这些指针每个都指向它们自己的一维实际对象数组。 这些缓冲区仅通过指针连接。

关联

 /* 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]; 

方法2(单缓冲,连续)

分配2D数组的另一种方法是使用单个缓冲区,然后基于2D坐标对其进行索引。 例如8 * 8 = 64.分配单个64字节缓冲区并且索引= x + y * 8.此方法连续存储数据,并且比方法1更容易分配和解除分配。

邻近的

 /* allocation */ int* array = malloc(sizeof(int) * width * height) /* indexing */ int item = array[x + y * width]; 

我想你是对的。 但是如果你真的希望数组是连续的,你可以将一个1Darraysmalloc并像2D一样使用它,就像

 int* oneDArray = (int*)malloc(sizeof(int)*10*10); int a = oneDArray[i*10+j]; //which equals to twoDArray[i][j]