2012-09-20 44 views
1

我創建了一個常規的dll,我有一個方法GetRecordRecordInfo結構分配內存。在DLL中分配完成時釋放客戶端中的內存?

struct RecordInfo{ 
    // Some Data member 
} 

BOOL GetRecord(RecordInfo *& pRecordInfo) 
{ 
    // Allocate RecordInfo, fill data and return as out paramter. 
} 

現在我從MFC應用程序和完成我的工作後訪問此dll。我使用delete在客戶端發佈RecordInfo。

delete pRecordInfo; 

在發佈模式下沒有問題,但在調試模式下,應用程序顯示斷言失敗。有人能解釋這種行爲背後的原因嗎?

+1

你好像有堆腐敗。您可以嘗試的一件事是在Visual Studio中啓用第一次機會異常,並查看是否可以找到損壞的原因。 – Naveen

+0

請注意,調試構建實際上是_helping_您的診斷基礎結構和相關的斷言失敗;而發佈版本正在悄然失敗。 (通常,在移植到發佈版本之前,應確保調試版本正常運行。) –

+0

您不能從一個分配器分配內存,然後將其釋放到另一個分配器。 –

回答

1

如果你想分配一個DLL內存和可用它在客戶端代碼,您應該確保DLL和客戶端與相同版本的編譯器同CRT「味道」的建(例如,兩者都是調試版本,或者兩者都是發佈版本)。

這當然是高度約束。

作爲替代,解耦事情做得更好,你可以從DLL函數導出到兩個分配取消分配你的數據結構(你的具體情況您可以添加並從您的DLL導出DeleteRecord功能,從該函數體內調用delete)。

,我建議你在舊的新博客閱讀this interesting blog post,並需特別注意的開始句(重點煤礦):

它應該是你的第二天性是其分配 內存和代碼的代碼這釋放了內存需要使用相同的分配器的

2

內存分配和取消分配應該在組件/ dll的同一側進行。

一個更優雅的解決方案是改爲填充std::unique_ptr<RecordInfo>

+3

'unique_ptr'只包含刪除,但實際的調用仍然由消費者(它有自己的模板副本)進行。 –

1

生產者和消費者需要就共同的分配器達成一致。在Windows世界中,最嚴格的選擇是CoTaskMemAlloc/CoTaskMemFree,它正是爲此目的而編寫的。

+0

可以使用CoTaskMemAlloc/CoTaskMemFree與常規的DLL,因爲這個DLL不使用任何MFC庫。 – MarsRover

+0

是的,這些功能真的很老,並且早於MFC。 :) –