2012-04-10 77 views
0

我有一个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:这两个“测试用例”都使用相同的编译器和标志进行编译,并针对相同的目标文件进行拼接。

编辑:

这里是“简单”的测试情况下,没有赛格故障工作:

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

的代码创建了一个赛格故障是班上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); 
} 

正如你所看到的,它是相当的从其余。我可能会尝试提取有问题的代码,但我认为这不会有太大的帮助。

+0

你能提供完整的测试案例吗? (失败的那个) – 2012-04-10 15:48:41

+0

奥利说什么:告诉我们你是如何使用这个类的。 – 2012-04-10 15:49:01

+0

简短的测试是没有问题的。长版本有几千行代码。我会尝试给出它的一部分 – 2012-04-10 15:50:25

回答

0

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

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

0

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

+0

我同意你的意见。但是如果我使用调试器,我输入构造函数Matrix22()。在开始时,堆栈没问题(通过'bt'检查)。循环结束后,堆栈已损坏。所以对我来说,很明显有问题的代码是在Matrix22()构造函数中。 PS:其他参数都是参考。它们在外面创建没有问题。如果他们是问题,我认为整个问题应该发生在另一个位置,还是我错了? – 2012-04-10 18:58:12