Ric*_*ndo 3 c arrays struct multidimensional-array dynamic-memory-allocation
我正在尝试实现类似于Conway的生活游戏的单元格网格。
虽然每个单独的网格在两个维度上都应具有固定的大小,但我希望有一个Grid结构可以在两个维度上都具有任意大小。
这类似于如何将数组设置为任意大小,但是一旦初始化后的数组将具有固定的大小。
这是我到目前为止的内容:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是我收到以下编译时错误:
main.c|12|note: declaration of `‘cell’ as multidimensional array must have bounds for all dimensions except the first|
Run Code Online (Sandbox Code Playgroud)
如何定义
Grid大小灵活的数据类型?
发布脚本:作为C新手,我认为以下方法会起作用:
typedef struct Grid {
unsigned width;
unsigned height;
Cell cell[width][height];
} Grid;
Run Code Online (Sandbox Code Playgroud)
发表评论后:每当我使用时,我总是不安malloc。我在这里正在做(或试图做)可怕的错误吗?
您无法使用cell[x][y]C中的双索引()来做到这一点,无法表达每行要跳转的字节数是动态的。
因此,最好的方法(我认为)是使用一维数组手动进行索引。
放一个平原:
Cell *cell;
Run Code Online (Sandbox Code Playgroud)
在struct(保持width和height)中,然后像这样进行索引:
set_cell(Grid *g, unsigned int x, unsigned int y, Cell value)
{
g->cell[y * g->width + x] = value;
}
Run Code Online (Sandbox Code Playgroud)
编译器将内联此代码的可能性不大,而且将会非常严格。可能比“锯齿状阵列”方法要快,后者使用更多的内存和另一层间接层。
分配很简单:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果您也想进行堆分配Grid,则可以将其与其元素一起分配。
是的,您需要free()在完成分配后进行分配,以免泄漏内存。严格来说,在现代系统上,无论程序何时结束,OS都将释放所有资源,但是无论如何,这都是释放代码的好方法:
void destroyGrid(Grid g)
{
free(g.cell);
}
Run Code Online (Sandbox Code Playgroud)