1. 主页
  2. 文档
  3. C语言教程
  4. C语言数组和字符串
  5. 如何在 C 中动态分配二维数组

如何在 C 中动态分配二维数组

以下是在堆上创建二维数组(或动态分配二维数组)的不同方法。
在以下示例中,我们将“ r ”视为行数,将“ c ”视为列数,我们创建了一个 r = 3、c = 4 和以下值的二维数组 

  1 2 3 4
  5 6 7 8
  9 10 11 12 

1) 使用单指针和带有指针运算的一维数组: 
一种简单的方法是分配大小为 r*c 的内存块并使用简单的指针运算访问其元素。 

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int r = 3, c = 4;

int* ptr = malloc((r * c) * sizeof(int));

/* Putting 1 to 12 in the 1D array in a sequence */
for (int i = 0; i < r * c; i++)
ptr[i] = i + 1;

/* Accessing the array values as if it was a 2D array */
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++)
printf("%d ", ptr[i * c + j]);
printf("\n");
}

free(ptr);

return 0;
}

输出: 

1 2 3 4
5 6 7 8
9 10 11 12

2) 使用指针数组 
我们可以创建一个大小为 r 的指针数组。请注意,从 C99 开始,C 语言允许使用可变大小的数组。创建指针数组后,我们可以为每一行动态分配内存。

#include <stdio.h>
#include <stdlib.h>

int main()
{
int r = 3, c = 4, i, j, count;

int* arr[r];
for (i = 0; i < r; i++)
arr[i] = (int*)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)
count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // Or *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

/* Code for further processing and free the
dynamically allocated memory */

for (int i = 0; i < r; i++)
free(arr[i]);

return 0;
}

输出: 

1 2 3 4 5 6 7 8 9 10 11 12

3) 使用指向指针的指针 
我们也可以使用双指针动态创建指针数组。一旦我们动态分配了一个数组指针,我们就可以像方法 2 一样为每一行动态分配内存。 

#include <stdio.h>
#include <stdlib.h>

int main()
{
int r = 3, c = 4, i, j, count;

int** arr = (int**)malloc(r * sizeof(int*));
for (i = 0; i < r; i++)
arr[i] = (int*)malloc(c * sizeof(int));

// Note that arr[i][j] is same as *(*(arr+i)+j)
count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

/* Code for further processing and free the
dynamically allocated memory */

for (int i = 0; i < r; i++)
free(arr[i]);

free(arr);

return 0;
}

输出: 

1 2 3 4 5 6 7 8 9 10 11 12

4) 使用双指针和一个 malloc 调用 

#include<stdio.h>
#include<stdlib.h>

int main()
{
int r=3, c=4, len=0;
int *ptr, **arr;
int count = 0,i,j;

len = sizeof(int *) * r + sizeof(int) * c * r;
arr = (int **)malloc(len);

// ptr is now pointing to the first element in of 2D array
ptr = (int *)(arr + r);

// for loop to point rows pointer to appropriate location in 2D array
for(i = 0; i < r; i++)
arr[i] = (ptr + c * i);

for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count; // OR *(*(arr+i)+j) = ++count

for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

return 0;
}

输出: 

1 2 3 4 5 6 7 8 9 10 11 12

5) 使用指向可变长度数组的指针。

VLA 的维度与变量的类型绑定。因此,一种形式是指向具有运行时定义形状的数组的指针。
在使用语法 (*arr)[i​​][j] 进行下标之前,必须取消对指针的引用。

#include <stdio.h>
#include <stdlib.h>

int main()
{
int r = 3, c = 4, i, j, count;

int (*arr)[r] = malloc(sizeof *arr);

count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
(*arr)[i][j] = ++count;

for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", (*arr)[i][j]);

free(arr);

return 0;
}

6) 使用指向 VLA 第一行的指针

与 5 类似,但允许使用 arr[i][j] 语法。

#include <stdio.h>
#include <stdlib.h>

int main()
{
int r = 3, c = 4, i, j, count;

int (*arr) = calloc(r, sizeof *arr);

count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
arr[i][j] = ++count;

for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", arr[i][j]);

free(arr);

return 0;
}

 

这篇文章对您有用吗?