直接调用GetDC是否会引发内存泄漏?OnEraseBackground中需调用ReleaseDC吗?
问题描述
我正在监听ON_WM_ERASEBKGND()消息,在对应的事件触发函数OnEraseBackground(CDC* pDC)中,通过以下代码修改背景色:
if (pDC) { pDC->SetBkColor(BlackColor); } else if (GetDC()) { GetDC()->SetBkColor(BlackColor); }
我的问题是:直接调用GetDC是否会造成内存泄漏?以及调用GetDC后是否需要调用ReleaseDC?
解答
- 直接调用
GetDC()且不释放会造成GDI资源泄漏(属于系统资源泄漏,并非传统堆内存泄漏)。系统的GDI资源总量有限,每次调用GetDC()都会分配一个设备上下文句柄,若不释放,这些句柄会持续被占用,累积到一定程度会导致程序无法创建新的GDI对象,甚至出现界面绘制异常、程序崩溃等问题。 - 调用
GetDC()后必须调用ReleaseDC()。GetDC()获取的是窗口共享的设备上下文,系统通过引用计数管理这类资源,只有调用ReleaseDC()才能将资源归还给系统,确保其他模块可以正常使用。
另外补充:OnEraseBackground函数的参数pDC是系统预先分配好传递过来的,不需要手动调用ReleaseDC释放,直接使用即可。而且通常情况下这个pDC不会为NULL,你代码里的else if分支大概率不会执行,但如果真走到这个分支,必须修正代码,先保存GetDC()的返回值,用完后释放:
else { CDC* pMyDC = GetDC(); if (pMyDC) { pMyDC->SetBkColor(BlackColor); ReleaseDC(pMyDC); } }
内容的提问来源于stack exchange,提问作者med
相关产品推荐
相关产品推荐

