不确定为什么但我使用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);
答案 0 :(得分:3)
您必须使用ReleaseDC()
释放GetDC()
返回的HDC。
请勿删除hbmOld
返回的SelectObject()
。只需将其选回HDC并让ReleaseDC()
处理其删除。
答案 1 :(得分:3)
在GetDC
之后,您必须致电ReleaseDC
- 而不是 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()
扔到这里,你肯定会有内存泄漏。这是非常好的静态分析器会告诉你的东西。