//dll執行緒代碼
char * p = (char*)malloc(sizeof(char) * 2048000);
memcpy(p, "Apple Phone", strlen("Apple Phone"));
p[strlen(p)] = '\0';
PostThreadMessage(g_dwThread, WM_TestMessage, 0, (LPARAM)p);
//main主執行緒訊息回圈
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
if (msg.message == WM_TestMessage)
{
printf("Get WM_TestMessage \n");
free((char*)msg.lParam);
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
這里有個疑問,執行緒的 指標變數 char *p 會因為dll結束后消失了。 而malloc的記憶體并沒有消失。 GetMessage 的 free((char*)msg.lParam); 是不是會有導致記憶體崩潰的可能?(我目前測驗是 還沒崩過), 請問有沒有方法讓GetMessage 正確處理dll里面的堆空間?
uj5u.com熱心網友回復:
DLL 中再添加一個匯出函式 用于釋放, 主執行緒中呼叫這個介面來釋放uj5u.com熱心網友回復:
最好的原則是誰申請誰釋放~uj5u.com熱心網友回復:
這個DLL 是 主程式在需要的時候通過 LoadLibrary加載的 ,然后DLL在 DllMain 的 DLL_THREAD_ATTACH: 創建一個 Settimer()作業。 把每次完成的任務結果通過PostThreadMessage給主執行緒處理。 不想通過DLL 提供介面完成這個事情(當然我記得Windows核心編程是建議Dll自己提供 申請 和 釋放...) 請問有其它方法嗎?
uj5u.com熱心網友回復:
可以用檔案的方式,DLL中創建、 寫檔案,關閉保存后,把檔案名傳遞給主執行緒,
主線中打開讀取,結束后洗掉
uj5u.com熱心網友回復:
謝謝提供方法。目前網上面查看另外一種方法利用了智能指標 按照里面的方法改了下代碼暫時也沒有問題
DLL執行緒:
PostMessage(MyhWnd, CWM_SOME_ERROR, 0, new string(the_exception.error_string));
主執行緒GetMessage
std::auto_ptr<string> msg(reinterpret_cast<string*>(lParam))
uj5u.com熱心網友回復:
"執行緒的 指標變數 char *p 會因為dll結束后消失了"dll結束 時 做 最后 一次 free
uj5u.com熱心網友回復:
誰申請誰釋放
dll匯出個free的函式。在main訊息回圈里用dll的free函式釋放即可。
uj5u.com熱心網友回復:
主執行緒和dll申請的記憶體都在同一個行程空間,所以我比較喜歡訊息佇列處理完畢后,訊息函式干掉傳過來的指標。
uj5u.com熱心網友回復:
如果在主執行緒GetMessage那個函式獲取訊息后怎么干掉傳趕來的指標? 在 PostThreadMessage那個執行緒里面創建的指標變數可能在主執行緒還沒執行完GetMessage的內容就沒了啊
uj5u.com熱心網友回復:
指標 - 》指向的記憶體(new或者malloc開辟的)怎么會沒了呢,沒有delete或free,它不會憑空沒的。
uj5u.com熱心網友回復:
在主執行緒中釋放uj5u.com熱心網友回復:
指標 - 》指向的記憶體(new或者malloc開辟的)
怎么會沒了呢,沒有delete或free,它不會憑空沒的。
void DllThread
{
char *p = (char*)malloc(sizeof(char) * 1024);
memcpy(p,"abcdefghijk",strlen("abcdefghijk");
p[strlen(p)] = '\0';
PostThreadMessage( nThreadId, WM__TEST_MESSAGE,NULL, p);
return;
}
int main()
{
GetMessage(...)
{
}
}
按照以上代碼, 在DllThread里面的PostThreadMessage不會阻塞,然后執行return,char *p 不就沒了嗎? 只是malloc的空間還在,然后泄露了?!
uj5u.com熱心網友回復:
。。。。指標變數p是區域變數是沒了,但是指標里存的地址值已經被放到訊息佇列里了。
你訊息處理的時候可以取出來,delete該地址所指向的記憶體塊。
建議樓主自己學會用編譯器看記憶體,理解不能停留在表面。
深刻去理解以下概念,進而深刻理解一個變數乃至一個物件的生與死,深刻理解變數的作用域
代碼區
區域變數
全域變數
堆
堆疊
靜態區
類變數
uj5u.com熱心網友回復:
懂的一點點表面的知識,去談記憶體泄漏是不科學。1、什么叫做記憶體泄漏?
2、什么情況下記憶體泄漏是危險的?
3、什么情況下記憶體泄漏是不危險的?
4、記憶體泄漏的本質是什么,你能不能寫出一個證明記憶體泄漏危害的例子?
5、絕大部分軟體都存在記憶體泄漏的情況,為什么系統不會掛掉?
c++初學者喜歡談面向物件,喜歡談記憶體泄漏,其實絕大部分都沒好好理解。
勿在浮沙筑高樓!
uj5u.com熱心網友回復:
上面講的有點那個,直白一些就是,別人講的是別人。你自己摸索了懂了才是你自己的。
嘗試一下吧,寫一個記憶體泄漏危害系統的程式,Hello記憶體內漏,祝君愉快踏入另一層次。
uj5u.com熱心網友回復:
CRT堆上的記憶體不能跨CRT堆釋放。所以DLL靜態鏈接CRT的話只能在DLL里釋放。就是匯出個函式專門干delete的活。DLL和Exe是共享的同一個CRT DLL的話,可以跨模塊去delete——前提是指標的型別在兩個模塊編譯出來行為相同。比如要是兩個模塊里同一個類的大小或者成員位元組對齊不一樣,你在一個模塊里去洗掉另一個模塊分配的類就有問題。當然char*這種簡單的型別沒有問題。不過簡單的記憶體分配可以直接在公用的堆上去申請記憶體,比如用CoTaskMemAlloc和CoTaskMemFree,這樣就沒有跨堆釋放的問題。uj5u.com熱心網友回復:
需要進行執行緒同步處理。定義信號量,在子執行緒PostThreadMessage后讓該執行緒處于等待狀態,主執行緒GetMessage處理完成后,改變信號狀態,子執行緒繼續運行free。
uj5u.com熱心網友回復:
智能指標的本意也還是誰申請誰釋放uj5u.com熱心網友回復:
用系統API申請記憶體不就完事了,HeapAlloc,HeapFree 跟哪個dll無關,隨便哪里釋放uj5u.com熱心網友回復:
1.申請全域記憶體,用于存盤訊息。2.阻塞式的發送訊息sendmessage,等訊息處理完成后才會回傳。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/25288.html
標籤:進程/線程/DLL
下一篇:cad圖形顯示問題求助
