2012-02-10 36 views
1

在Windows中,如何將GlobalAlloc替換爲new在Windows中,如何用`new`替換`GlobalAlloc`?

你好, 我有此代碼段(從這裏:"Reading from a Mailslot") 與GlobalAlloc分配內存。

DWORD cbRead = 0; 
LPTSTR lpszBuffer = (LPTSTR) ::GlobalAlloc(GPTR, cbMessage); //cbMessage is from a call to GetMailslotInfo 
if(NULL == lpszBuffer) 
    return FALSE; 
lpszBuffer[0] = '\0'; 
BOOL fResult = ::ReadFile(hSlot, lpszBuffer, cbMessage, &cbRead, 0); 
if (fResult) 
{ 
    _tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer); 
} 
::GlobalFree((HGLOBAL) lpszBuffer); 

我想改變的代碼,並使用智能指針代替裸LPTSTR(和擺脫GlobalFree)和new代替GlobalAlloccbMessage是「下一個消息的大小,以字節爲單位」,所以我需要類似malloc這對於無類型內存的作品,有沒有適合我的情況的任何形式的new

+0

此代碼在'fResult == FALSE'時泄漏。 – tibur 2012-02-10 19:51:03

+0

@tibur是的,我會解決它。謝謝。 – 2012-02-10 19:52:35

+1

是的,只需撥打新電話。請記住考慮sizeof(TCHAR)。另外,爲什麼你還有'TCHAR'。這是很久以前的事了。 – 2012-02-10 19:55:51

回答

3

通常,你不能。

不同的內存分配函數(GlobalAllocmallocnewSysAllocVirtualAllocHeapAlloc)的存在是因爲它們以不同的方式,不同的地方,不同的大小分配內存,不同的標記它,用不同的底層管理人員,以及其他無數的差異。它們中的一些在本地堆中,一些是全局的,一些是虛擬的,一些沒有指定,其他的分配內存並對它做些事情,比如SysAllocString,其他與CoGetMalloc一起使用的COM等等。

如果調用指定使用一個分配器,則可能有底層代碼將內存傳遞給另一個進程或某些其他需要該分配器的行爲。你可以嘗試使用另一個,但它可能是未定義的行爲。

爲了與其他分配器一起使用智能指針,您可以執行一些操作。最簡單的方法是將它們作爲分配器和釋放器函數提供給智能指針類,從而使其能夠正確處理事情。根據您選擇的指針,這可能需要進行一些調整,或者您可能必須將能夠與該分配器一起工作的基本智能指針放在一起。

對於常見的問題,MFC和/或ATL通常具有智能指針和輔助函數,它們可以與一個或多個專用分配器一起工作。如果使用這些是可能的,你可以看看。

+3

但在代碼給出沒有發生。 – 2012-02-10 20:05:52

1
boost::scoped_array<TCHAR> buffer(new TCHAR[cbMessage/sizeof(TCHAR)]); 
buffer[0] = 0; 
BOOL fResult = ::ReadFile(hSlot, buffer.get(), cbMessage, &cbRead, 0); 
if (fResult) 
{ 
    _tprintf(TEXT("Contents of the mailslot: %s\n"), buffer.get()); 
} 

這使用智能指針來管理內存,所以你不需要明確地釋放它。 (A boost scoped_array。)

+0

@alf你不能直接寫入std :: string的內存。我同意T的東西是無稽之談,但這與問題似乎沒有關係。對於有興趣轉向智能指針的人來說,提升會非常有用。 – 2012-02-10 20:15:46

+1

對不起,但你錯了std :: string。對不起,但Boost對於我能想象到的任何東西都是不必要的。標準庫有足夠好的智能指針。 – 2012-02-10 20:19:27

+1

@ AlfP.Steinbach,好點,但我不認爲它證明-1。問題中沒有任何內容表明這不是MBCS上的遺留代碼。雖然智能指針還有其他選擇,但這並不意味着這個選擇錯了 - 它是爲這種情況設計的。 – 2012-02-10 20:32:46

相關問題