【发布时间】:2012-03-14 17:26:53
【问题描述】:
以前,我只是使用 malloc 处理这些类型的 __out 函数参数,但我正在尝试改变我的方式。
作为一个具体的例子,在一个管理原始输入的类中,GetRawInputDeviceInfo()的原型是这样的:
UINT GetRawInputDeviceInfo(HANDLE, UINT, LPVOID, PUINT)
LPVOID 是指向包含我需要的信息的缓冲区的指针。 PUINT 是一个指向 UINT 的指针,该 UINT 包含 LPVOID 指向的缓冲区中包含的数据大小。
通常,我会(一旦我填充了 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/free,并具有 RAII 的精神:)
【问题讨论】:
-
sizeof(&cbSize)将始终是 PUINT* 的大小,假设 32 位拱门为 4 个字节...因此您总是分配 4 个字节,可以吗?我不知道 *cbSize 应该是什么值。