我遇到了由於我的dll和我的實際項目中的不同CRT設置(MTd MDd)而導致的堆腐敗。 我發現奇怪的是,當我將dll中的析構函數設置爲虛擬時,應用程序只會崩潰。 有沒有一個簡單的解釋呢?我知道我不能釋放那些不在我的堆上的內存,但是當我將析構函數定義爲非虛擬的時候,其中的差異究竟在哪裏。CRT虛擬析構函數
一些代碼只是爲了更清晰一點
的DLL
#pragma once
class CTestClass
{
public:
_declspec(dllexport) CTestClass() {};
_declspec(dllexport) virtual ~CTestClass() {};
};
而且我的項目
int main(int argc, char* argv[])
{
CTestClass *foo = new CTestClass;
delete foo; // Crashes if the destructor is virtual but works if it's not
}
此外,你是否有同樣的問題,通過將declspec移動到* class *('class _declspec(dllexport)CTestClass {...}')並刪除每個成員declspecs?只是好奇。注意,調用代碼和DLL應該使用相同的CRT(調試或發佈),因此需要考慮。我甚至不確定混合模式是否受支持(我不認爲它是)。 – WhozCraig
您的流程中有多個CRT副本。你只導出類方法,而不是v表。試圖理解這一切如何相互作用來轟炸你的代碼並不是那麼有效,這是可以預料的。使用虛擬方法導出類需要導出整個類,並將__declspec(dllexport)放在* class *關鍵字旁邊。而且您必須確保使用單個分配器來創建和銷燬該對象。很難保證,除非你始終用/ MD編譯並使用完全相同的編譯器版本。在模塊邊界上暴露C++類是有風險的。 –
你是對的,即使我找出爲什麼它不起作用,它不會幫助我太多。感謝你的想法:) – Poisonbox