在C中如何动态创建一个二维数组

3
我无法使用两个变量创建一个二维数组(例如 int arr[i][j] 不被允许),那么我该如何创建一个大小可动态调整的二维数组呢?
在我的程序中,数组的尺寸只能在运行时确定。该数组用于表示一个网格。请问我应该如何在C语言中编写这个代码呢?

C99允许你声明VLA - 变长数组 - 所以,如果你有一个C99编译器和没有人为的(作业)限制,你可以写出精确的代码 int arr[i][j];。 (如果你没有C99编译器,现在是时候获取一个了。)话虽如此,你打算如何访问数组? 你可以希望使用arr[i][j]来访问元素,或者你可以准备使用类似于arr[i*n+j]的计算来访问它。对于这两种情况,所需的内存分配模式是完全不同的。 - Jonathan Leffler
5个回答

11

首先分配一个指针数组。

/* size_x is the width of the array */
int **array = (int**)calloc(size_x, sizeof(int*));
然后分配每一列。
for(int i = 0; i < size_x; i++) 
{
    /* size_y is the height */
    array[i] = (int*)calloc(size_y, sizeof(int));
}

你可以使用array[i][j]来访问元素。释放内存的顺序是“相反”的:

for(int i = 0; i < size_x; i++) 
{
    free(array[i]);
}
free(array);

我在VS2010中遇到了一个错误,提示无法将void转换为int。因此,我不得不使用(int**)显式地进行强制类型转换为int **。因此,第一行变成了int **array = (int**)calloc(size_x, sizeof(int*)),第二行也需要使用(int*) - JaBe
1
@JaBe 在C++中你必须显式地进行类型转换。但是,既然你在使用C++,为什么还要使用calloc呢? - Staven
我正在使用C++并调用许多无法更改的C代码。使用C++ vec调用看起来并不好:https://dev59.com/xVnUa4cB1Zd3GeqPY0Ib - JaBe
1
那个for循环的限制应该是size_x而不是size_y吗? - jterm

8

您需要分配一个一维数组:

int* array = calloc(m*n, sizof(int));

并且这样访问它:

array[i*n + j]

编译器在访问二维数组时会执行类似操作,并且当n可以在编译时推断出时,可能会输出相同的代码。

1
这是关于comp.lang.c的常见问题解答(我添加了c-faq标签),甚至还有一个FGA(经常给出的答案 :-) 请参见 http://c-faq.com/aryptr/index.html,6.16 如何动态分配多维数组?

0

一些示例展示了数组的多个(超过2个)分配;对于n×m数组,只需进行两次分配(省略错误检查)即可完全实现:

int **array = calloc(m, sizeof(*array));
int *data   = calloc(m * n, sizof(*data));

for (int i = 0; i < m; i++)
    array[i] = &data[i * n];


...use array[i][j]...

free(array[0]);
free(array);

0

在C语言中,多维数组只是每个元素都是另一个数组的数组。

因此,您需要首先为一个数组(行)分配内存。您可以使用malloc()函数,它将返回指向数组的指针。

然后,您遍历数组,并为每个元素分配列数的内存。

注意:不要忘记使用free()函数释放手动分配的内存,就像您使用malloc()函数分配内存一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接