void *从函数 - 堆损坏返回的指针 [英] void* pointer returned from Function - Heap Corruption
问题描述
以前,我只是使用malloc处理这些类型的__out函数参数,但是我试图改变我的方式。
在管理原始输入的类中,GetRawInputDeviceInfo()原型如下:
UINT GetRawInputDeviceInfo(HANDLE,UINT,LPVOID,PUINT )
LPVOID是指向包含所需信息的缓冲区的指针。 PUINT是指向包含由LPVOID指向的缓冲区中的数据大小的UINT的指针。
通常,我会(一旦填充PUINT):
PUINT cbSize; //假设它的大小正确,包含正确的
//数据长度
LPVOID buffer =(LPVOID)malloc(sizeof(& cbSize));
GetRawInputDeviceInfo(XXX.handle,RIDI_DEVICENAME,buffer,cbSize);
//做某事w /缓冲
free(buffer);
现在,试图这样做没有malloc,我会写:
(对不起,
PUINT cbsize; //假设它的大小正确并包含正确的
//数据长度
1以下声明和使用示例:
LPVOID unique_ptr:
std :: unique_ptr< LPVOID>缓冲;
GetRawInputDeviceInfo(xxx.handle,RIDI_DEVICENAME,buffer.get(),
cbSize);
UINT unique_ptr:
std :: unique_ptr< UINT>缓冲;
GetRawInputDeviceInfo(xxx.handle,RIDI_DEVICENAME,
(LPVOID)buffer.get(),cbSize);
Raw UINT指针:
UINT * buffer = NULL;
GetRawInputDeviceInfo(xxx.handle,RIDI_DEVICENAME,
(LPVOID)buffer,cbSize);
然后读取缓冲区:
OutputDebugString((LPCSTR)buffer)//为unique_ptr添加.get()
事情是,缓冲区包含我想要的信息,它的输出应该是!但是,当unique_ptr超出范围并被删除(或UINT *被删除),我得到一个堆的腐败异常。我走过代码,发生了什么是一旦GetRawInputDeviceInfo函数运行,我所有的类级容器/变量都有他们的数据重写。例如,上面的序列出现在一个for循环中,我的迭代器从0(第一次迭代)到80837436(大约),所有其他变量局部变量被弄乱了。
那么,我如何检索缓冲区中的信息,而不用将其他所有东西都拧紧呢?最好不要使用malloc / free,而要使用RAII的精神:
-
获取名称所包含的字符数
UINT char_count;
GetRawInputDeviceInfo(xxx.handle,RIDI_DEVICENAME,NULL,& char_count);
-
分配足够长的字符串缓冲区,并检索名称
std :: unique_ptr< wchar_t []> buf(new wchar_t [char_count]);
GetRawInputDeviceInfo(xxx.handle,RIDI_DEVICENAME,buf.get(),& char_count);
您的范例程式码不会造成堆损坏。可能你的真正的代码使用一个未初始化的 buffer
,这导致GetRawInputDeviceInfo写入数据到一些非预期的位置。
Previously, I'd just dealt with these types of __out function parameters using malloc, but I'm trying to change my ways.
As a specific example, in a class to manage Raw Input, GetRawInputDeviceInfo() is prototyped as such:
UINT GetRawInputDeviceInfo(HANDLE, UINT, LPVOID, PUINT)
LPVOID is a pointer to a buffer containing the information I need. PUINT is a pointer to a UINT containing the size of data contained in the buffer pointed to by LPVOID.
Normally, I would (once I have populated the 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);
Now, attempting to do this without malloc, I would write: (sorry, I'm typing this from work, so I may botch this from memory)
PUINT cbsize; // assume it is sized correctly and contains the proper
// length of data
1 of the following declaration and use examples: 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);
Raw UINT Pointer:
UINT *buffer = NULL;
GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME,
(LPVOID)buffer, cbSize);
Then reading the buffer:
OutputDebugString((LPCSTR)buffer) //add .get() for unique_ptr
The thing is, the buffer contains the information I want, and it's outputted as it should be! However, when the unique_ptr goes out of scope and is deleted (or the UINT* is deleted), I get a Heap Corruption exception. I stepped through the code and what happens is once the GetRawInputDeviceInfo function runs, ALL of my class level containers/variables have their data rewritten. For example, the above sequence appears in a for loop, and my iterator goes from 0 (first iteration) to 80837436 (or so), and all other variables local variables are messed up.
So, how can I retrieve the information in the buffer without screwing everything else up? And preferably without using malloc/free, and with the spirit of RAII :)
The correct way to use GetRawInputDeviceInfo is
Get the number of characters the name contains
UINT char_count; GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, NULL, &char_count);
Allocate a long enough string buffer, and retrieve the name
std::unique_ptr<wchar_t[]> buf (new wchar_t[char_count]); GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, buf.get(), &char_count);
Your example code won't cause heap corruption. Probably your real code uses an uninitialized buffer
, which caused GetRawInputDeviceInfo to write data to some unintended location.
这篇关于void *从函数 - 堆损坏返回的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!