我正在尝试实现一个单元格网格,类似于康威的生命游戏。
虽然每个单独的网格在两个维度上都应具有固定大小,但我想要一个允许在两个维度上具有任意大小的网格结构。
这类似于数组可以是任意大小,但数组一旦初始化就具有固定大小。
这是我目前所拥有的:
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
中(保留 width
和 height
)然后索引如下:
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/