2016-07-29 5 views
3

У меня возникают проблемы с утечкой памяти HDC. Могли бы вы, ребята, проверить, правильно ли я снимаю/удаляю HDC?Утечка памяти HDC (высвобождение HDC/удаление hdc)

Спасибо!

BITMAP bm; 
HBITMAP hbmap; 
HBITMAP hBitmapOld; 
BITMAPINFO bmi; 
HDC hdcShot; 

...

while(true) 
{ 
    if (!TakeScreenshot(GameWindow, bm, hbmap, bmi, hdcShot, hBitmapOld, appWnd)) 
        break; 

     HBITMAP hbmapNew = CreateCompatibleBitmap(hdcShot, rcWindow.right - rcWindow.left, rcWindow.bottom - rcWindow.top); 

     HDC hdcShotNew = CreateCompatibleDC(hdcShot); 

     HBITMAP OldBmp = (HBITMAP)SelectObject(hdcShotNew, hbmapNew); 


     BitBlt(hdcShotNew, 0, 0, rcWindow.right - rcWindow.left/*Window WIDTH*/, rcWindow.bottom - rcWindow.top/*Window HEIGHT*/ 
      , hdcShot, 0, 0, SRCCOPY); 


     pPixels = new RGBQUAD[bm.bmWidth * bm.bmHeight]; 
     if (!pPixels) return false; 

     SelectObject(hdcShotNew, OldBmp); 


     if (!GetDIBits(hdcShotNew, hbmapNew, 0, bm.bmHeight, pPixels, &bmi, DIB_RGB_COLORS)) 
     { 
      DeleteDC(hdcShot); 
      delete[] pPixels; 

      return false; 
     } 



// dont mind about this 
     ScanContents scanContentsMain(bm, rcWindow, pPixels); 
// dont mind about this 
     ScanBMPHorizontal(&scanContentsMain); 




     //free memory - I might have cleared the memory incorrectly here! Please check! 
     free(pPixels); 
     SelectObject(hdcShot, hBitmapOld); 
       DeleteDC(hdcShot); 
       DeleteObject(hbmapNew); 
       DeleteDC(hdcShotNew); 
} 

TakeScreenShot Func (не очень важно, но это показывает, как некоторые переменные инициализируются)

bool TakeScreenshot(std::string WindowToFind, BITMAP &bm, HBITMAP &hbmap, BITMAPINFO &bmi, HDC &hdcShot, HBITMAP &hBitmapOld, HWND &hwnd) 
{ 
    RECT rc; 
    GetWindowRect(hwnd, &rc); 
    hdcShot = CreateCompatibleDC(0); 
    hbmap = CreateCompatibleBitmap(GetDC(0), rc.right - rc.left/*Window WIDTH*/, rc.bottom - rc.top/*Window HEIGHT*/); 

    SelectObject(hdcShot, hbmap); 


    BitBlt(hdcShot, 0, 0, rc.right - rc.left/*Window WIDTH*/, rc.bottom - rc.top/*Window HEIGHT*/ 
     , GetDC(0), rc.left, rc.top, SRCCOPY); 

//Ignore this 
    if (!GetObject(hbmap, sizeof(BITMAP), (LPSTR)&bm)) 
     return false; 
    int bitsPerPixel = bm.bmBitsPixel; 


//Ignore this 
    if (bitsPerPixel != 32 || bm.bmPlanes != 1) 
     return false; 

//Don't mind about this too much 
    SetupBitmapInfo(bmi, bm.bmWidth, bm.bmHeight, bitsPerPixel); 


    return true; 

} 

Я проверил с deleakers и узнал, что я борясь с утечкой HDC. Я не уверен, что я сделал неправильно.

+0

Вы случайно вызывающие различные функций. Это удаляет неинициализированные переменные, выбирая неинициализированный объект в DC, удаляя другие объекты, которые, вероятно, не должны быть удалены. Работает ли этот код вообще? –

+0

Он делает. Это только часть полного исходного кода. На самом деле это работает. крошечный бит просочившейся памяти просто складывается с течением времени. – user3518291

+0

@BarmakShemirani Пожалуйста, посмотрите на мои свободные функции памяти. Я думаю, что я мог бы неправильно освободить память. [Добавлена ​​функция TakeScreenShot] – user3518291

ответ

4

У вас есть утечка ресурсов здесь:

hbmap = CreateCompatibleBitmap(GetDC(0), rc.right - rc.left, rc.bottom - rc.top); 

Вы должны изменить к

HDC hdc = GetDC(0); 
CreateCompatibleBitmap(hdc, rc.right - rc.left, rc.bottom - rc.top); 
... 
ReleaseDC(0, hdc);//call this before exiting the function 

free(pPixels) неправильно (хотя она все еще чистит в данном случае). Заменить free(pPixels) с delete[]pPixels

Изменения этого:

SelectObject(hdcShot, hBitmapOld); 
DeleteDC(hdcShot); 
DeleteObject(hbmapNew); 
DeleteDC(hdcShotNew); 

Для этого:

SelectObject(hdcShot, OldBmp); 
DeleteObject(hbmapNew); 
DeleteObject(hBitmapOld); 
DeleteDC(hdcShot); 
DeleteDC(hdcShotNew); 
+0

Я думаю, что этот ответ может подвести итог. Я проверю его, когда вернусь на свой компьютер завтра. Спасибо! – user3518291