我正在编写C代码,我想堆分配512 * 256字节。为了方便起见,我希望能够使用语法数组[a] [b]访问元素;没有算术来找到正确的索引。
我在网上看到的每个教程都告诉我要创建一个指针数组,指向我在数组中想要的行数组。这意味着每个子数组都需要单独进行malloc和free。我感兴趣的是一个只需要一次调用malloc和一次调用free的解决方案。(因此所有元素都是连续的)我认为这是可能的,因为我不会构造一个锯齿状数组。
如果有人可以分享声明这样一个数组的语法,我将不胜感激。
答案 0 :(得分:39)
好吧,如果要分配类型数组,可以将其分配给该类型的指针。
由于2D数组是数组数组(在您的情况下,是一个包含256个字符的512个数组的数组),您应该将其分配给指向256个字符数组的指针:
char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;
(*arr
周围的括号是使它成为指向数组的指针,而不是指针数组)
答案 1 :(得分:14)
如果像这样分配数组,则需要两次调用free
,但它允许array[a][b]
样式语法并且是连续的。
char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
array[i] = array[0] + (256 * i);
有关详细信息,请参阅此处array2
:http://c-faq.com/aryptr/dynmuldimary.html
答案 2 :(得分:12)
这很容易假设您不需要与古老的C89标准兼容(在当前的C编译器中,只有MSVC和一些嵌入式目标编译器是倒退的)。这是你如何做到的:
int (*array)[cols] = malloc(rows * sizeof *array);
然后array[a][b]
对a
中的[0,rows)
和b
中的[0,cols)
有效。
在C标准的语言中,array
具有可变修改类型。如果要将指针传递给其他函数,则需要在函数参数列表中重复此类型,并确保至少将列数传递给函数(因为它需要作为可变修改的一部分)类型)。
编辑:我错过了OP只关心固定大小512x256的事实。在这种情况下,C89就足够了,您只需要:
int (*array)[256] = malloc(512 * sizeof *array);
如果你需要在函数之间传递指针(并且还作为函数返回类型,可以在函数参数列表中使用完全相同的类型,但是对于这种用法,你可能想要输入它...: - )< / p>
答案 3 :(得分:5)
由于您提前了解了数组的大小,因此可以创建一个包含521x256数组的struct
类型,然后动态分配struct
。
答案 4 :(得分:2)
如果您知道数组的大小,可以typedef
它,并指向它。这是一个简短的片段,演示了这种用法:
#include <stdio.h>
#include <stdlib.h>
typedef int array2d[20][20];
int main() {
int i,j;
array2d *a = malloc(sizeof(array2d));
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
(*a)[i][j] = i + j;
for(i=0;i!=20;i++)
for(j=0;j!=20;j++)
printf("%d ",(*a)[i][j]);
free(a);
return 0;
}
答案 5 :(得分:2)
可以动态分配相同类型的多维数组
static char x[512][256];
给你,但由于类型衰减,这很麻烦。我只知道如何使用typedef
:
typedef char row[512];
row *x = malloc(sizeof(row) * 256);
这只允许您在运行时确定第二个维度的大小。如果两个维度在运行时都有所不同,则需要一个涂料矢量。
答案 6 :(得分:0)
所有很棒的答案。对于像我这样喜欢在旧机器上使用诸如 Turbo C 之类的旧编译器进行 16 位“复古”编码的老怪人,我只想添加一件事。可变长度数组很棒,但不是必需的。
char (*array)[81];
int lineCount;
/* Go get your lineCount.*/
lineCount = GetFileLines("text.fil");
array = malloc(lineCount * 81);
这就是我们过去制作“VLA”的方式。它的工作原理与
完全相同 char (*array)[81] = malloc(lineCount * 81); /* error pre C99 */
没有 VLA 的奢华。
只是我旧的和失去光泽的 2 美分。