我有一个Matrix22
带有数组和默认构造函数的 C++ 类:
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:两个“测试用例”都使用相同的编译器和标志编译,并且还链接到相同的目标文件。
编辑:
这是没有段错误的“简单”测试用例:
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);
}
如您所见,它完全来自其他地方。我可能会尝试提取有问题的代码,但我认为这不会有太大帮助。