堆分配一个2D数组(不是指针数组)

Pau*_*aul 25 c malloc multidimensional-array

我正在编写C代码,我想堆分配512*256字节.为了方便起见,我希望能够使用语法数组[a] [b]访问元素; 没有算术来找到正确的索引.

我在网上看到的每个教程都告诉我要创建一个指针数组,指向我在数组中想要的行数组.这意味着每个子数组都需要单独进行malloc和free.我感兴趣的,只需要调用一次malloc和一个呼叫免费的解决方案.(因此,所有的元素是连续的),我认为这是可能的,因为我不会构建一个交错的数组.

如果有人可以分享声明这样一个数组的语法,我将不胜感激.

asa*_*elr 39

好吧,如果要分配类型数组,可以将其分配给该类型的指针.

由于2D数组是数组的数组(在您的情况下,是一个包含256个字符的512个数组的数组),您应该将其分配给指向256个字符数组的指针:

char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;
Run Code Online (Sandbox Code Playgroud)

(周围的括号*arr是使它成为指向数组的指针,而不是指针数组)

  • 请注意,由于C99,在编译时不再需要知道维度.你可以从stdin读取`n,m`并声明`char arr [n] [m]`,或者在这种情况下,`char(*arr)[n]`. (4认同)

Mat*_*ert 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);
Run Code Online (Sandbox Code Playgroud)

有关array2更多信息,请参见此处:http://c-faq.com/aryptr/dynmuldimary.html

  • 这不是二维数组,而是指针数组.它有一些优点(你可以置换O(1)中的行而不是O(cols))和其他缺点(每次访问都更昂贵,因为它经历了额外的间接级别;它需要更多的内存;等等).无论如何,如果你采用这种方法,考虑Zack的建议只使用一个`malloc`.这简化了您的错误处理(没有部分故障情况来清理)并确保内存局部性. (4认同)
  • 您可以通过在dope向量之后立即放置数据块来组合这两个分配.需要一定数量的繁琐的类型转换,但并不难.但是,你所显示的代码有一个严重的错误:你为512`coun`s分配空间,然后你将它视为512`char*s的足够空间.这几乎可以保证在分配和崩溃结束时走开. (3认同)

R..*_*R.. 12

假设您不需要与古老的C89标准兼容(在当前的C编译器中,只有MSVC和一些嵌入式目标编译器是倒退的),这很容易.这是你如何做到的:

int (*array)[cols] = malloc(rows * sizeof *array);
Run Code Online (Sandbox Code Playgroud)

然后array[a][b]对任何ain [0,rows)bin 有效[0,cols).

在C标准的语言中,array具有可变修改类型.如果要将指针传递给其他函数,则需要在函数参数列表中重复此类型,并确保至少将列数传递给函数(因为它需要作为可变修改的一部分)类型).

编辑:我错过了OP只关心固定大小512x256的事实.在这种情况下,C89就足够了,您只需要:

int (*array)[256] = malloc(512 * sizeof *array);
Run Code Online (Sandbox Code Playgroud)

完全相同的类型可以在函数参数列表中使用,如果你需要的是传递指针功能之间(也作为函数的返回类型,但对于这种使用你可能想的typedef它... :-)


tru*_*ity 5

由于您提前知道了数组的大小,因此可以创建一个struct包含521x256数组的类型,然后动态分配struct.