我有一个结构“单元格”定义为
typedef struct{
int id;
terrainType terrain;
} cell;
然后我制作一个二维单元格数组
cell** makeCellGrid(int sizeX, int sizeY)
{
cell** theArray;
int i;
theArray = (cell**) malloc(sizeX*sizeof(cell*));
for ( i = 0; i < sizeX; i++)
{
theArray[i] = (cell*) malloc(sizeY*sizeof(cell));
}
return theArray;
}
起初我认为这工作正常,但后来出现了一些段错误,我发现使用某些值(例如 makeCellGrid(32, 87) )它会中断。
我对 C 指针和内存垃圾相当新鲜,希望有人能在这里为我指明正确的方向。
使用较低的数字界限,我可以毫无问题地访问它
map[i][j].id = x;
等等
编辑:忘记添加,从测试中,段错误源自
theArray[i] = (cell*) malloc(sizeY*sizeof(cell));
最佳答案
该代码缺少对 malloc()
的错误检查系统调用。
因此,如果第一次调用 malloc()
第二个失败(在循环中)尝试将内存分配给 NULL
这确实会导致您正在目睹的分段违规。
您可能会考虑像这样修改您的代码:
#include <stdlib.h>
typedef struct {
int id;
TerrainType terrain;
} CellType;
void freeCellGrid(CellType ** ppCells, size_t sizeX)
{
size_t i = 0;
for (; i < sizeX; ++i)
{
free(ppCells[i]);
}
free(ppCells);
}
CellType ** makeCellGrid(size_t sizeX, size_t sizeY)
{
CellType ** ppCells = malloc(sizeX * sizeof(*ppCells));
if (ppCells)
{
size_t i = 0;
for (; i < sizeX; ++i)
{
ppCells[i] = malloc(sizeY * sizeof(**ppCells));
if (NULL == ppCells[i])
{
freeCellGrid(ppCells, i);
ppCells = NULL;
break;
}
}
}
return ppCells;
}
关于我的修改的注意事项:
malloc()
的情况下返回错误 NULL
)unsigned
访问内存/数组索引的类型; size_t
是为了这个 void *
返回的值。功能类似于 malloc()
pp
来表示这是一个 2 级间接)CellType
) 开头类型名称和使用小写字母 ( ppCells
) 开头的变量。 sizeof
的参数总是更安全。运算符然后是某种类型。由于分配内存的指针的声明可能会在开发过程中更改,并将参数调整为malloc()
。会被遗忘。简而言之:像我一样做是不容易出错的。 freeCellGrid()
)。最好先编码这个释放器,然后在编码分配器的错误处理时手动编写它(如第二次调用 malloc()
所示)。 关于c - 二维数组分配的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14826958/