void *从函数 - 堆损坏返回的指针 [英] void* pointer returned from Function - Heap Corruption

查看:164
本文介绍了void *从函数 - 堆损坏返回的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前,我只是使用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的精神:

解决方案

使用 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写入数据到一些非预期的位置。


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

  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.

这篇关于void *从函数 - 堆损坏返回的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆