2012-03-14 98 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