不知道为什么,但我使用Deleaker插件来检测内存泄漏。在我调试构建的代码中,它说我在GetDC有内存泄漏,而在发布构建中,它说我在CreateCompatibleDC有泄漏
这些是真的泄密还是假的?当我的类关闭时,我的delete对象被调用。
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);发布于 2016-02-27 00:32:18
必须使用ReleaseDC()来释放GetDC()返回的HDC。
不要删除SelectObject()返回的hbmOld。只需将其选回HDC,并让ReleaseDC()处理其删除。
发布于 2016-02-27 00:53:09
在GetDC之后,您必须调用ReleaseDC-not DeleteDC。DeleteDC仅与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()在这里抛出,你肯定会有内存泄漏。这也是一个真正优秀的静态分析器会告诉你的。
https://stackoverflow.com/questions/35656160
复制相似问题