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
Allocate a long enough string buffer, and retrieve the name
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.