您的位置:首页 > 其它

LoadBitmap返回的HBITMAP未删除导致的内存泄漏问题

2011-09-27 17:42 369 查看
最近写程序检查某个工程的内存泄漏问题,检查很久,修修补补,也补了部分内存泄漏问题,但是在画界面部分还是存在内存泄漏,而且经常间歇性才发作,百思不得其解,找了很多资料无果,只能自己一句句代码查找,功夫不负有心人最后让我发现了。。。

原来有内存泄漏的代码:

void CWinXXXDlg::OnPaint()

{

CDC dcMem;

CBitmap bmpMem;

BITMAP bm2;

CBitmap *pOldBm2=NULL;

dcMem.CreateCompatibleDC(&dc);

bmpMem.CreateCompatibleBitmap(&dc,800,480);

CBitmap *pOldBm=dcMem.SelectObject(&bmpMem);

CDC dcMem2;

dcMem2.CreateCompatibleDC(&dcMem);

CBitmap bmpMem2;

bmpMem2.Attach(::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND))); //背景

bmpMem2.GetBitmap(&bm2);

pOldBm2=dcMem2.SelectObject(&bmpMem2);//选BITMAP

dcMem.BitBlt(0,0,800,480,&dcMem2,0,0,SRCCOPY); //画背景位图

dcMem2.SelectObject(pOldBm2);//选回旧的bitmap进行清理内存

bmpMem2.Detach();

dcMem.SelectObject(pOldBm);//选回旧的bitmap进行清理

bmpMem.DeleteObject();

bmpMem2.DeleteObject();

dcMem.DeleteDC();

dcMem2.DeleteDC();

}

咋一看,好像没什么问题。

这程序在Timer中每100ms 运行一次this->Invalidate(0),我测试的WINCE 6中运行一直内存稳定,但是到了1个小时左右内存会迅速以4KB的速度一直减少

一直想不明白,最后发现原来是LoadBitmap惹的祸。

原程序中为了方便,将Attach和LoadBitmap写在了一条语句,但是LoadBitmap会返回一个HBITMAP的GDI句柄,MSDN中说到:

The application must call the DeleteObject function to delete each bitmap handle returned by the LoadBitmap function.

就是因为写在了一条语句上,所以忽略了它的返回值,导致有句柄没有删除引起内存泄漏。

原因知道了,下面改写代码:

void CWinXXXDlg::OnPaint()

{

CDC dcMem;

CBitmap bmpMem;

BITMAP bm2;

CBitmap *pOldBm2=NULL;

dcMem.CreateCompatibleDC(&dc);

bmpMem.CreateCompatibleBitmap(&dc,800,480);

CBitmap *pOldBm=dcMem.SelectObject(&bmpMem);

CDC dcMem2;

dcMem2.CreateCompatibleDC(&dcMem);

CBitmap bmpMem2;

HBITMAP hbitmap=::LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_BACKGROUND));//改成返回hbitmap

bmpMem2.Attach(hbitmap); //通过句柄进行Attach背景

bmpMem2.GetBitmap(&bm2);

pOldBm2=dcMem2.SelectObject(&bmpMem2);//选BITMAP

dcMem.BitBlt(0,0,800,480,&dcMem2,0,0,SRCCOPY); //画背景位图

dcMem2.SelectObject(pOldBm2);//选回旧的bitmap进行清理内存

DeleteObject(hbitmap);//最后还要使用这个删除HBITMAP句柄

bmpMem2.Detach();

dcMem.SelectObject(pOldBm);//选回旧的bitmap进行清理

bmpMem.DeleteObject();

bmpMem2.DeleteObject();

dcMem.DeleteDC();

dcMem2.DeleteDC();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: