c - 在struct中需要一个 "variable"大小的二维数组

标签 c arrays multidimensional-array struct dynamic-memory-allocation

我正在尝试实现一个单元格网格,类似于康威的生命游戏。

虽然每个单独的网格在两个维度上都应具有固定大小,但我想要一个允许在两个维度上具有任意大小的网格结构。

这类似于数组可以是任意大小,但数组一旦初始化就具有固定大小。

这是我目前所拥有的:

typedef struct Cell {
    int data;
    // stuff to be added later
} Cell;

typedef struct Grid {
    unsigned width;
    unsigned height;
    Cell cell[][];
} Grid;

Grid initGrid(unsigned width, unsigned height) {
    Grid g;
    g.width = width;
    g.height = height;
    g.cell = malloc( sizeof(Cell)*width*height );
    return g;
}

但是我得到以下编译时错误:

main.c|12|note: declaration of `‘cell’ as multidimensional array must have bounds for all dimensions except the first|

How can I define a Grid data type with flexible size?

Post scriptum:作为 C 新手,我认为以下内容可行:

typedef struct Grid {
    unsigned width;
    unsigned height;
    Cell cell[width][height];
} Grid;

Post post scriptum: 每当我使用malloc 时,我总是感到不安。我在这里做(或试图做)任何可怕的错误吗?

最佳答案

你不能用 C 中的双索引 (cell[x][y]) 来做到这一点,没有办法表示每行要跳转的字节数是动态的。

因此,最好的(在我看来)方法是使用一维数组手动进行索引。

放一个普通的:

Cell *cell;

struct 中(保留 widthheight)然后索引如下:

set_cell(Grid *g, unsigned int x, unsigned int y, Cell value)
{
  g->cell[y * g->width + x] = value;
}

编译器不太可能将其内联,而且会非常紧凑。可能比使用更多内存和另一层间接寻址的“锯齿状数组”方法更快。

分配很简单:

Grid initGrid(unsigned int width, unsigned int height)
{
    Grid g;
    g.width = width;
    g.height = height;
    g.cell = malloc(width * height * sizeof *g.cell);
    // add assert or error here, can't return NULL for value type
    return g;
}

如果您也想对 Grid 进行堆分配,您可以将其与其元素共同分配。

是的,您需要在完成分配后free() 分配,以免内存泄漏。严格来说,在现代系统上,操作系统将在程序结束时释放所有资源,但无论如何释放都是一种很好的形式:

void destroyGrid(Grid g)
{
  free(g.cell);
}

关于c - 在struct中需要一个 "variable"大小的二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49300051/

相关文章:

python - Numpy:多维数组值内的比较

c++ - 如何在执行回调时隐藏顶级 GTK 窗口

c - 如何从用户那里获取两个二进制数和运算并给出答案

javascript - 如何根据 AJAX 响应动态创建 ARRAY?

java - FindBugs 提出了一个名为 EI_EXPOSE_REP 的错误,该错误由 Array 引起

python - Numpy 如何推断数组的 dtype

c - ssize_t 和 size_t 给出不同的值

c++ - C 预处理器 - 现有定义的前置路径

java - 为什么从基元创建数组会复制它们?

Javascript多维数组完整列获取设置