如何在 C 中声明可变大小的二维数组?

Posted

技术标签:

【中文标题】如何在 C 中声明可变大小的二维数组?【英文标题】:How to declare a variable size 2D array in C? 【发布时间】:2012-03-12 00:12:14 【问题描述】:

我的项目有问题。我必须制作一个可变大小的二维数组来存储一些预测错误......所以这是关于图像的。问题是我必须加载不同大小的图像,因此对于每个图像,我必须将具有相应像素数的二维数组放入一个文件中。我已经在你的问题中进行了搜索,但这不是我正在寻找的有谁能帮帮我吗?

谢谢

【问题讨论】:

【参考方案1】:

如果您在函数范围内有现代 C 编译器(至少 C99),那么它很简单:

unsigned arr[n][m];

这称为可变长度数组 (VLA)。如果数组太大,可能会出现问题。因此,如果您有大图像,您可以这样做:

unsigned (*arr)[m] = malloc(sizeof(unsigned[n][m]));

以后

free(arr);

【讨论】:

请记住,上面提到的可变长度数组将被分配到堆栈上。与问题不太相关的第二件事是 C++ 0X 不支持此功能(但是,由于这是一个 C 问题,所以工作正常) @Yavar,这就是为什么我还提到了使用malloc 分配的版本。即便如此,它也是一种“可变修改类型”。而且 C++ 显然还有其他方法来处理多维数组,所以是的,这根本不相关。【参考方案2】:

如果您需要内存是连续的,您有几个选择。

您可以动态分配单个内存块,然后手动计算偏移量,如下所示:

size_t rows, cols;
...
int *arr = malloc(sizeof *arr * rows * cols);
...
arr[i * rows + j] = ...; // logically equivalent to arr[i][j]

您可以在主数组中设置第二个指针数组:

int **arrp = malloc(sizeof *arrp * rows);
...
for (i = 0; i < rows; i++)
  arrp[i] = &arr[i * rows];
...
arrp[i][j] = ...;

记住你必须释放 两个 arrarrp

如果你有一个 C99 实现,你可以设置一个指向 VLA 的指针,像这样:

int (*arrp)[cols] = (int (*)[cols]) arr;
...
arrp[i][j] = ...;

请注意,在这种情况下,您不需要为辅助数组分配任何内存,也不需要手动计算指向主数组的指针;您所要做的就是将arrp 设置为与arr 相同的位置,然后让指针运算规则完成所有工作。

如果图像不是那么大,您可以设置一个 VLA(同样,C99 或更高版本):

int arr[rows][cols];

但实际上这不是一个好主意;堆栈帧的大小通常非常有限。

【讨论】:

在您的第三种情况下,我认为分配更好,因为我在回答中给出了它。直接malloc就行了,不用强制转换,只会混淆。【参考方案3】:

您需要动态分配内存。使用双指针逻辑。

例如:

int n=10; <<-u can change this.
int **a;
a=(int **)malloc(sizeof(*int)*n);
for (int i=0;i<n;i++)
 a[i]=(int *)malloc(sizeof(int)*n);// or *(a+i)

【讨论】:

当然不是,但你可以让它表现得像一个数组 当您可以简单地使用二维数组时,为什么还要使用模拟? 嗯,这就是原生 C 语言的局限性。动态数组创建,或者说一般的内存分配是 C 语言的一个主要缺陷,让人们望而却步。它仍然是一门很好的语言,因为它赋予了原始力量。这个例子证明了你可以做一些低级的操作来达到预期的结果.. 但是你还是没有回答我的问题。 C 具有动态分配的多维数组。为什么你会模仿语言提供的功能? 恐怕你错了。我不了解 C99 标准,但 K&RC(原始版本)等旧版本不支持“int a[m][n];”之类的东西。

以上是关于如何在 C 中声明可变大小的二维数组?的主要内容,如果未能解决你的问题,请参考以下文章

具有可变大小行的 C++ 二维数组

C 语言二级指针作为输入 ( 二维数组 | 二维数组遍历 | 二维数组排序 )

C语言实现一个可变长的二维数组

opencl核函数怎么传二维数组实参

C程中如何计算数组(一维及二维)占内存空间的大小

传递可变大小的多维数组