释放内存失败,位图DC为什么不能释放

我做了个查看位图的程序,每次换图时需要把前一图申请的内存释放掉,但是每次free完就产生异常

if (data != NULL)
                {
                    DeleteObject(hBit);
                    ReleaseDC(hWnd,memDC); //并不能释放DC,每次返回的都是0
                    ReleaseDC(hWnd,winDC);
                    DeleteObject(memDC); //只有这样才能释放
                    free(data); //产生异常
                }
                szFile = OpenBmp(hWnd);
                if (szFile != NULL)
                {
                    wcscpy_s(fName, lstrlen(szFile) * 2, szFile);
                }
                else
                    return NULL;
                hFile = CreateFile(fName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
                R = ReadFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &num, NULL);
                if (R)
                {
                    R = ReadFile(hFile, &fif, sizeof(BITMAPINFOHEADER), &num, NULL);
                    winDC = GetDC(hWnd);
                    memDC = CreateCompatibleDC(winDC);
                    GetClientRect(hWnd, &rect);
                    dataSize = bfh.bfSize - bfh.bfOffBits;
                    data = (BYTE*)malloc(dataSize);

                    pbmi.bmiHeader = fif;
                    width = fif.biWidth;
                    height = fif.biHeight;

                    hBit = CreateDIBSection(memDC, &pbmi, DIB_RGB_COLORS, (void**)&data, NULL, 0);
                    R = ReadFile(hFile, data, dataSize, &num, NULL);
                    SelectObject(memDC, hBit);
                    open = TRUE;
                    InvalidateRect(hWnd, &rect, TRUE);

                }
                CloseHandle(hFile);

看看句柄是否有效,是否已经释放过了

该回答引用GPTᴼᴾᴱᴺᴬᴵ
在释放位图数据前,您需要确保相关的设备上下文(DC)已经被释放掉。在您的代码中,似乎是释放了两次设备上下文 memDC,其中一次是通过 DeleteObject(memDC) 释放的,而第二次是通过 ReleaseDC(hWnd, memDC) 释放的。然而,ReleaseDC() 函数是用来释放设备上下文而不是位图,因此释放位图时不应该使用该函数。正确的做法是使用 DeleteDC() 函数来释放 memDC,例如:

if (data != NULL)
{
    DeleteObject(hBit);
    DeleteDC(memDC);  // 释放设备上下文
    ReleaseDC(hWnd, winDC);
    free(data);
}


另外,由于您在申请内存时使用了 malloc() 函数,因此在释放内存时应该使用 free() 函数。如果申请内存时使用了其他函数(例如 GlobalAlloc()),则需要使用相应的函数来释放内存。