2012-04-10 60 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