在WM_DROPFILES之后堆积在free()上的损坏

时间:2014-08-27 05:54:30

标签: c++ c winapi

我必须使用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}},则完全正常。这是为什么?

这与顶级答案所建议的过早释放无关,停止提升。如果是这种情况,这个问题就不会是堆腐败,而是会导致访问冲突。

2 个答案:

答案 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);
}