我必须对一些内存进行malloc,以便在此消息上为WPARAM创建一个奇怪的结构,但在调用PostMessage后,我无法释放内存,而程序会崩溃,说存在堆损坏。
void DropFileMsg(HWND hWind,char* file_path)
{
DROPFILES* drop_data = (DROPFILES*)malloc(2048);
char* files = (char*)drop_data+sizeof(DROPFILES);
ZeroMemory(drop_data,2048);
drop_data->pFiles = sizeof(DROPFILES);
drop_data->pt.x=0;
drop_data->pt.y=0;
drop_data->fNC=false;
drop_data->fWide=false;
strcpy(files,file_path);
PostMessage(hWind, WM_DROPFILES, (WPARAM)drop_data, NULL);
free(drop_data);
}
堆损坏错误:为RtlGetUserInfoHeap(002F000000300018)指定的地址无效
这在没有free
的情况下工作得很好,也没有PostMessage
,但两者都不工作。为什么会这样?
这与顶部答案中建议的过早释放无关,停止投票。如果是这样的话,这个问题就不会涉及堆损坏,而是会导致访问冲突
这可能是因为WM_DROPFILES
消息的收件人使用了指针,但您已经对其进行了未分配,因此指针现在指向未分配的内存,并且您有未定义的行为。
与其释放内存,为什么不让收件人在完成后释放内存呢?
这个问题的其他答案都是错误的
在阅读了Windows源代码中的rdrag.c之后,它看起来像DragFinish,由接收进程从拖放中调用,在HDROP结构上调用GlobalFree。
考虑到这一点,我已经将我的代码更改为以下代码:
void DropFileMsg(HWND hWind,char* file_path)
{
DROPFILES* drop_data = (DROPFILES*)GlobalAlloc(GPTR,2048);
char* files = (char*)drop_data+sizeof(DROPFILES);
drop_data->pFiles = sizeof(DROPFILES);
drop_data->pt.x=0;
drop_data->pt.y=0;
drop_data->fNC=false;
drop_data->fWide=false;
strcpy(files,file_path);
PostMessage(hWind, WM_DROPFILES, (WPARAM)drop_data, NULL);
}