在类中访问malloc'd 2d数组时出现Seg Fault

时间:2015-07-15 17:52:51

标签: c++ arrays malloc

这是一个包含名为“map”的二维chars数组的类。首先,我将[mapDimension] char * s分配给char **。然后,我将[mapDimension]字符分配给每个char *。我这样做而不是静态:char map [mapDimension] [mapDimension]因为虽然这适用于小数字,但一旦mapDimension超过2500,它也会段错误。我想在堆上而不是堆栈上分配内存,以便我可以容纳更多。

构造函数中的最后两行是将2d数组中的每个char初始化为0,然后将中心1设置为5。

#define mapDimension 1000    

class Field 
{
private:
    int i;
public:
    char** map = (char**)malloc(mapDimension * sizeof(char*));
    Field()
    {
        for(i = 0; i < mapDimension; i++)
            map[i] = (char*)malloc(mapDimension * sizeof(char));
        memset(map, 0, mapDimension*mapDimension*sizeof(char));
        map[mapDimension/2][mapDimension/2] = 5;
    }
};

int main()
{
    Field field;
    return 0;
}

这种动态方法也是段错误。我做错了什么?

3 个答案:

答案 0 :(得分:4)

    memset(map, 0, mapDimension*mapDimension*sizeof(char));

您正在清除map数组(指针数组),因此map [x]现在包含NULL。您可能应该在循环中使用map[i]来清除已分配的内存。

<强> BUT

  1. 当你分配内存时,你应该释放它(有malloc,没有免费可见)
  2. 在C ++中使用new[]delete[]代替malloc
  3. 更好 - 使用std::vector<std::vector<char>>

答案 1 :(得分:2)

此声明无效

memset(map, 0, mapDimension*mapDimension*sizeof(char));

你分配了几个内存区而不是一个连续的存储区。

你必须使用一个循环。例如

    for ( i = 0; i < mapDimension; i++ ) memset( map[i], 0, mapDimension );

你的类必须有一个析构函数来释放分配的内存。

例如

~Field()
{
    for( i = 0; i < mapDimension; i++ ) free( map[i] );
    free( map );
}

最好使mapDimensionsize_t类型的静态常量变量,而不是使用宏定义。

考虑到在C ++中你应该使用运算符new而不是C函数malloc

此外,您只需使用容器std::vector<std::string>而不是手动分配的数组。

答案 2 :(得分:0)

  • 首先,可以分配您的数组,以便您可以一次性memset整个阵列。{li}但为此你必须将第二级内存分配为一个连续内存块,然后在行之间分配

    Field()
    {
      char *data_memory = (char *) malloc(mapDimension * mapDimension * sizeof(char));
    
      for (i = 0; i < mapDimension; i++)
        map[i] = data_memory + i * mapDimension;
      ...
    }
    
  • 其次,如果您将分配方法更改为&#34;单个块分配&#34; (如上所述)然后为了memset整个事情,你必须按照以下方式进行

    memset(map[0], 0, mapDimension * mapDimension * sizeof(char));
    

    memset(&map[0][0], 0, mapDimension * mapDimension * sizeof(char));
    

    注意memset的第一个论点。

    但如果你坚持使用当前的分配方法,那么你可以忘记在整个数组上使用memset。您的数组在内存中不连续。你无法memset整个事情。您所能做的只是memset每一行

    for (i = 0; i < mapDimension; i++)
      memset(map[i], 0, mapDimension * sizeof(char));
    
  • 第三,将i声明为类的成员,而不是使用局部变量i是个坏主意。此外,为frist malloc使用类内初始化程序也是一个坏主意。此外,在C ++中,您应该优先使用new/new[]而不是malloc,甚至没有提到您应该优先使用std::vector而不是手动数组内存管理。