void* pointer returned from Function - Heap Corruption

Deadly 提交于 2019-12-11 07:26:28

问题


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 :)


回答1:


The correct way to use GetRawInputDeviceInfo is

  1. Get the number of characters the name contains

    UINT char_count;
    GetRawInputDeviceInfo(xxx.handle, RIDI_DEVICENAME, NULL, &char_count);
    
  2. 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.



来源:https://stackoverflow.com/questions/9706960/void-pointer-returned-from-function-heap-corruption

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!