26

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

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

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

4

7 回答 7

42

好吧,如果要分配类型的数组,请将其分配给该类型的指针。

由于二维数组是数组的数组(在您的情况下,是 512 个 256 个字符的数组的数组),您应该将它分配给一个指向 256 个字符的数组的指针:

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

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

于 2012-04-12T02:37:11.603 回答
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

于 2012-04-12T01:51:22.563 回答
14

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

int (*array)[cols] = malloc(rows * sizeof *array);

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

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

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

int (*array)[256] = malloc(512 * sizeof *array);

如果您需要在函数之间传递指针(也可以作为函数返回类型,但对于这种用途,您可能需要对它进行 typedef... :-)

于 2012-04-12T02:39:40.770 回答
5

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

于 2012-04-12T01:56:55.623 回答
4

可以动态分配相同类型的多维数组

static char x[512][256];

给你,但由于类型衰减,这有点棘手。我只知道如何使用typedef

typedef char row[512];
row *x = malloc(sizeof(row) * 256);

这只允许您在运行时确定第二维的大小。如果两个维度在运行时都可以变化,则需要一个涂料向量。

于 2012-04-12T02:01:23.510 回答
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;
}
于 2012-04-12T02:00:43.630 回答
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 ​​美分。

于 2021-04-13T03:15:33.173 回答