繁体   English   中英

HDC内存泄漏

[英]HDC memory leak

不知道为什么,但是我使用Deleaker插件来检测内存泄漏。 在我的代码中,在debug中建立它的说法是我在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);

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

不要删除SelectObject()返回的hbmOld 只需将其选择回HDC中,然后让ReleaseDC()处理其删除即可。

GetDC之后,必须调用ReleaseDC 而不是 DeleteDC DeleteDC仅与CreateCompatibleDC一起CreateCompatibleDC 如果您忘记了这些,请在文档中详细说明。

另外,您错误地清理了设备上下文。 将手柄保存到旧对象的原因是可以将它们重新选择到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方式包装这些本机资源的库(构造函数获取;析构函数发布)将是一个不错的主意。 它不仅使您不必记住每次清理的详细信息,而且还可以确保代码是异常安全的。 如果将func()丢到这里,肯定会发生内存泄漏。 这也是一个非常好的静态分析器会告诉您的信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM