为什么编译器没有在堆栈上保留足够的空间?

时间:2012-04-10 15:46:59

标签: c++ multidimensional-array linker stack segmentation-fault

我有一个带有数组和默认构造函数的C ++类Matrix22

class Matrix22{
  /* something more */
  double mat[2][2];
  Matrix22(){
    for(int i=0; i<2; i++)
      for(int j=0; j<2; j++)
        mat[i][j] = i==j ? 1.0 : 0.0;
  }
};

我在我的程序中使用它并且出现了分段错误。由于其余部分非常困难和复杂,我编写了一个简单的测试例程,只调用Matrix22()。没有更多的错误。

然后我运行gdb来调试问题。如果我从单独的测试例程调用构造函数,gcc会为成员mat保留一些内存。我可以在堆栈中导航并在数组之后的某些字节处查看返回地址。

在主程序中,编译器没有预留足够的空间。第一个元素(mat[0][0])被写入,但任何进一步的写入只会覆盖下一个堆栈帧。我还可以验证在构造函数之前,命令bt返回正确的回溯,在关键赋值之后,回溯已损坏。

所以我的问题是:为什么在一种情况下编译器(或链接器?)为数组保留的空间不足,而在另一种情况下没有发生呢?

PS:两个“测试用例”都使用相同的编译器和标志进行编译,并针对相同的目标文件进行了修改。

编辑:

这是一个没有seg错误的“简单”测试用例:

void test_Matrix22()
{
  Framework::Math::Matrix22 matrix;
}

创建seg错误的代码在类ModuleShaddower中(混合标题和实现):

class ModuleShaddower{
    public:
        ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position);
    private:
        Matrix22 rotMatrix90;
};

ModuleShaddower::ModuleShaddower(PVModule& module, const EnvironmentalSetup& setup, const Position& position)
  : module (module), position(position), setup(setup), logger(LoggerFactory::getLoggerInstance())
{
    double mat[][2] = {{0, -1},{1, 0}}; // This line will never be reached
    rotMatrix90 = Matrix22(mat);
}

如你所见,它完全来自其他人。我可能会尝试提取有问题的代码,但我认为这无济于事。

2 个答案:

答案 0 :(得分:0)

如果未达到ModuleShaddower构造函数代码(根据您的代码注释),那么构造函数初始化列表中的某些内容(与模块的构造,可能性等相关)会导致问题。

答案 1 :(得分:0)

问题是由于不同位置的两个目标文件具有相同的名称。在由此对象代码创建的结果静态库中,有时会替换错误的文件(两者都被称为Shaddower.o)。当我重命名其中一个文件时,一切顺利,没有更多的错误。

我不知道这个问题的确切根源,但它可以像这样解决。