WM_DROPFILES之后的free()上出现堆损坏



我必须对一些内存进行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);
}

最新更新