来自2d阵列分配的c-seg错误



我有一个结构"cell"定义为

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;  
}  

一开始我认为这很好,但后来出现了一些seg错误,我发现在某些值(例如makeCellGrid(32,87))下它会崩溃。我对C指针和内存垃圾还很熟悉,希望有人能给我指明正确的方向。

有了较低的数字边界,我用访问它没有问题

map[i][j].id = x;

等等

编辑:忘记添加,从测试来看,seg故障源自

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;  
} 

我的修改说明:

  • 始终检查系统调用是否存在错误(在返回错误NULLmalloc()的情况下)
  • 更好地使用unsigned类型来访问存储器/阵列标记;size_t用于此
  • 在C中,不需要强制转换void *函数(如malloc())返回的值
  • 始终尝试尽快初始化变量;未初始化的变量很容易导致应用程序的"非理性"行为
  • 如果使用指针,将间接级别"编码"到它们的名称中可能会很有帮助(我在这里使用前缀pp来表示这是一个2级间接)
  • 类型不同于变量:区分这一点的一种方法是用大写字母(CellType)开始类型名称,用小写字母(ppCells)开始变量名称
  • 如果将内存分配给指针,并且所分配内存的大小适合指针的类型很重要,那么使用(取消引用的)指针本身作为sizeof运算符的参数总是比使用某种类型更安全。由于内存分配给的指针的声明可能会在开发过程中发生变化,并且会忘记将参数调整为malloc()。简而言之:像我那样做不太容易出错
  • 如果封装结构(包括阵列)的动态创建,那么还可以实现一种取消分配的方法(此处:freeCellGrid())。更好的做法是,首先对这个deallocator进行编码,因为在对分配器的错误处理进行编码时,您可以手动使用它(如对malloc()的第二次调用所示)

相关内容

  • 没有找到相关文章

最新更新