2012-03-14 70 views
1

以前,我只是使用malloc處理了這些類型的__out函數參數,但我試圖改變我的方式。void *從函數返回的指針 - 堆損壞

作爲具體的例子,在一個類來管理原始輸入,GetRawInputDeviceInfo()是原型爲這樣:

UINT GetRawInputDeviceInfo(HANDLE, UINT, LPVOID, PUINT) 

LPVOID是一個指針,指向包含我所需要的信息的緩衝器。 PUINT是指向包含由LPVOID指向的緩衝區中包含的數據大小的UINT的指針。

通常情況下,我會(我一旦填充PUINT):

PUINT cbSize; // assume it is sized correctly and contains the proper 
       // length of data 

LPVOID buffer = (LPVOID)malloc(sizeof(&cbSize)); 
GetRawInputDeviceInfo(XXX.handle, RIDI_DEVICENAME, buffer, cbSize); 
//do something w/buffer 
free(buffer); 

現在,試圖做到這一點沒有malloc的,我會寫: (抱歉,我下班打字,所以我可以從存儲器糟蹋此)

PUINT cbsize; // assume it is sized correctly and contains the proper 
       // length of data 

下面的聲明1,並使用實施例: LPVOID的unique_ptr:

std::unique_ptr<LPVOID> buffer; 
GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, buffer.get(), 
         cbSize); 

UINT的unique_ptr:

std::unique_ptr<UINT> buffer; 
GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, 
         (LPVOID)buffer.get(), cbSize); 

原UINT指針:

UINT *buffer = NULL; 
GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, 
         (LPVOID)buffer, cbSize); 

然後讀取緩衝區:

OutputDebugString((LPCSTR)buffer) //add .get() for unique_ptr 

的事情是,緩衝區包含了我想要的信息,這是輸出應該是!但是,當unique_ptr超出範圍並被刪除(或UINT *被刪除)時,我會遇到堆損壞異常。我介紹了代碼,發生了什麼事情,一旦GetRawInputDeviceInfo函數運行,我的所有類級容器/變量都會重寫它們的數據。例如,上面的序列出現在for循環中,並且我的迭代器從0(第一次迭代)變爲80837436(大約),並且所有其他變量局部變量都被混淆了。

那麼,我怎樣才能檢索緩衝區中的信息,而不是把所有的東西都搞砸了?而且最好不使用malloc /免費,並與RAII :)

+2

'sizeof(&cbSize)'將永遠是一個PUINT *的大小,4個字節,假設32位拱...因此,你總是malloc'ing 4個字節,可以嗎?我無法確定* cbSize應該是什麼值。 – SirDarius 2012-03-14 17:33:09

回答

3

的精神,使用GetRawInputDeviceInfo正確的方法是

  1. 獲取的字符數的名稱中包含

    UINT char_count; 
    GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, NULL, &char_count); 
    
  2. 分配足夠長的字符串緩衝區,並檢索名稱

    std::unique_ptr<wchar_t[]> buf (new wchar_t[char_count]); 
    GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, buf.get(), &char_count); 
    

您的示例代碼不會導致堆損壞。可能您的真實代碼使用未初始化的buffer,從而導致GetRawInputDeviceInfo將數據寫入某個非預期位置。

+0

謝謝。這工作完美。我從中學到了很多東西。 – Lokked 2012-03-15 00:20:40