2010-08-13 176 views
8

我正在使用Visual Studio中的Win32 C++應用程序。析構函數崩潰

在其中一個源文件中,我有如下所示的全局對象。

TestClass tObj; 

int main() //Execution starts here 
{ 
} 

TestClass在下面的其他DLL中定義。

struct Source 
{ 

}; 

class TestClass 
{ 
    list<Source> sourceList; 
    public: 
     TestClass() {} 
     ~TestClass() {} 
}; 

雖然我的應用程序正在運行,如果我嘗試通過關閉控制檯窗口顯式關閉應用程序, ,它在識別TestClass析構函數崩潰。 Callstack顯示CrtIsValidHeapPointer失敗。

請幫我解決這個問題。

+0

使用四個空格縮進代碼,而不使用正常文本。 – 2010-08-13 09:07:01

+1

您是否使用相同的C++運行庫構建了exe和DLL? – Mark 2010-08-13 09:09:43

+0

是的,我建立了與Visual Studio。只有配置類型不同。一個是exe,另一個是Project配置中的DLL配置。 – bjskishore123 2010-08-13 09:13:59

回答

4

確保您使用相同的運行時構建殭屍程序EXE和DLL,最好是使用動態運行時。

+0

崩潰通過在exe和dll中使用相同的運行時庫來解決。謝謝大家幫助我。 – bjskishore123 2010-08-13 09:34:27

1

它在析構函數中崩潰,析構函數正在調用terminate和crash應用程序時拋出一個異常。 Uncaught exceptions

存在調用析構函數的兩種情況。第一種情況是當一個對象在「正常」條件下銷燬時,例如,當它超出範圍或被明確刪除時。第二種是在異常傳播的堆棧展開部分期間異常處理機制銷燬對象時。你必須在保守的假設下編寫你的析構函數,因爲如果控制由於異常而離開析構函數而另一個異常處於活動狀態,C++將調用終止函數

+0

全局對象在main()被調用之前正在構建。 所以我認爲,它的破壞發生在main()退出後。 那時,STL內部使用的列表 sourceList頭在釋放時無效。因此CrtIsValidHeapPointer失敗。 – bjskishore123 2010-08-13 09:15:50

+0

現在的問題是:爲什麼sourceList頭是無效的?如果您的exe和DLL使用兼容的運行時正確構建,那麼此代碼應該可以正常工作。運行時將在釋放堆之前清理全局對象。 – 2010-08-13 09:23:37

+0

崩潰是通過在exe和dll中使用相同的運行時庫來解決的。 謝謝大家的幫助。 – bjskishore123 2010-08-13 09:31:17

1

全局對象被初始化並被C運行時。它們在main被調用並在其返回之後被初始化。

該錯誤可能是由您的TestClass析構函數(或間接來自Source析構函數)訪問的內容引起的。析構函數代碼正在訪問無效內存(或已被釋放的內存)。

未定義初始化和全局變量銷燬的順序,並且經常是應用程序終止時的錯誤源。如果還有其他全局變量可能會清理或修改TestClass引用的資源,那麼這可能是罪魁禍首。

+0

我沒有添加任何節點到sourceList(列表)。 析構函數調用時列表爲空。 但是,STL List在內部仍然會有一個隱藏的Head指針。當試圖釋放它,它崩潰。 – bjskishore123 2010-08-13 09:20:30

+0

您正在構建EXE和DLL的哪個CRT? – 2010-08-13 09:25:11

0

DLL和EXE是否使用相同的對齊(pack pragma)構建?

9

您的問題是不同的。exe之間的編譯器/連接設置和.dll有效引起.dll和.exe要使用標準庫的不同實現的是:

  • 您必須使用相同的預處理器標記*來構建.exe和.dll,否則每個二進制文件都將使用細微的不同實現進行編譯。
  • 您必須將.exe和.dll都鏈接到動態運行時。與運行時靜態鏈接的二進制文件將獲得自己的堆 - 然後最終分配到一個堆上,並試圖釋放另一個堆。

要解決此問題,請轉至Project > Properties > Configuration Properties > C/C++ > Code Generation並將運行時庫選項更改爲Multi-threaded Debug DLL (/MDd)。您必須爲.exe項目和.dll項目執行此操作。

由於Visual Studio 2010中的,其中一些樣的錯誤都將在鏈接時使用#pragma detect_mismatch檢測。

* 對於擁有標準庫實現

+0

'+ 1'從我這個全面的答案。 @ bjskishore123:請閱讀[FAQ](http://stackoverflow.com/faq)。我們鼓勵你接受你最能幫助你解決問題的答案。 – sbi 2010-08-13 16:30:10

0

嘗試的任何效果,使您的構造函數和析構函數非內聯,它可以幫助所有的預處理器標誌。如果ctor和dtor不是內聯的,則兩者都將以dll的名義生成,因此將使用相同的運行時庫執行列表<>的構建和銷燬。 通常,儘量避免通過dll邊界傳遞不透明的stl對象。最好將它們作爲privatte成員封裝到您自己的類中,並提供非內聯方法來操作此類成員