我必须使用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指定的地址无效(002F0000,00300018)
如果没有free
,并且没有PostMessage
但没有{{1}},则完全正常。这是为什么?
这与顶级答案所建议的过早释放无关,停止提升。如果是这种情况,这个问题就不会是堆腐败,而是会导致访问冲突。
答案 0 :(得分:4)
这可能是因为WM_DROPFILES
消息的收件人使用了指针,但您已经取消分配它,因此指针现在指向未分配的内存,并且您有undefined behavior。
而不是释放内存,为什么不让收件人在完成后释放内存?
答案 1 :(得分:-1)
其他答案在这个问题上是错误的。
在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);
}