HDC内存泄漏

时间:2016-02-26 15:53:14

标签: c++ winapi

不确定为什么但我使用Deleaker插件来检测内存泄漏。 在我的代码中调试构建它的说法我在GetDC有内存泄漏 然后在发布版本中,它说我在CreateCompatibleDC

有泄漏

这些真实的泄漏还是假的? 我的班级关闭时会调用我的删除对象。

    HDC hdc = GetDC(_hWnd);
    _hdcMem = CreateCompatibleDC(hdc);
    HBITMAP hbmOld = (HBITMAP)SelectObject(_hdcMem, _hBitmap);

    while (_execute.load(std::memory_order_acquire)) 
    {
        func();

        BitBlt(hdc, 0, 0, _Width, _Height, _hdcMem, 0, 0, SRCCOPY);
    }

    SelectObject(_hdcMem, hbmOld);
    DeleteDC(_hdcMem);
    DeleteObject(hbmOld);
    DeleteObject(_hBitmap);
    DeleteDC(hdc);

2 个答案:

答案 0 :(得分:3)

您必须使用ReleaseDC()释放GetDC()返回的HDC。

请勿删除hbmOld返回的SelectObject()。只需将其选回HDC并让ReleaseDC()处理其删除。

答案 1 :(得分:3)

GetDC之后,您必须致电ReleaseDC - 而不是 DeleteDCDeleteDC仅与CreateCompatibleDC一起使用。如果您忘记了,我们会在the documentation中详细说明。

此外,您错误地清理了设备上下文。将句柄保存到旧对象的原因是您可以重新选择到DC中。你无法删除它们!选择到设备上下文中的对象无法删除 - 它们正在使用中。 (如果您正在检查这些API函数的返回值,您会知道,因为它们会返回错误。)

代码应如下所示:

HDC hdc = GetDC(_hWnd);

_hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmOld = (HBITMAP)SelectObject(_hdcMem, _hBitmap);

while (_execute.load(std::memory_order_acquire)) 
{
    func();

    BitBlt(hdc, 0, 0, _Width, _Height, _hdcMem, 0, 0, SRCCOPY);
}

SelectObject(_hdcMem, hbmOld);
DeleteObject(_hBitmap);
DeleteDC(_hdcMem);

ReleaseDC(_hWnd, hdc);

我不清楚为什么在_hdcMem_hBitmap使用全局变量时,它们的范围仅限于这一段代码。您在顶部创建它们,并在底部销毁它们,因此它们在此代码之外是无用的。您应该将其范围限制为代码的这一部分。能够推断对象/变量的生命周期是解决内存泄漏的关键。

请注意,使用在RAII fashion(构造函数获取;析构函数发布)中包装这些本机资源的库将是一个很好的主意。它不仅使您不必记住每次清理的详细信息,而且还确保您的代码是异常安全的。如果func()扔到这里,你肯定会有内存泄漏。这是非常好的静态分析器会告诉你的东西。