首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

有没有泄漏

2013-01-23 
有没有泄露啊例子1:函数 :{CRect rtGetClientRect(&rt)CDC* pDcGetDC()if(!m_dcMemory.CreateCompatib

有没有泄露啊

例子1:


函数 :
{
CRect rt;
GetClientRect(&rt);

CDC* pDc=GetDC();

if(!m_dcMemory.CreateCompatibleDC(pDc))
{
ReleaseDC(pDc);
::PostQuitMessage(0);
}

// 创建兼容位图
m_Bmp.CreateCompatibleBitmap(pDc, rt.Width(), rt.Height());
m_dcMemory.SelectObject((HGDIOBJ)m_Bmp);//有意:不返回旧的位图


//第三个dc
HBITMAPhBitmap=(HBITMAP)LoadImage(0,"c:\\1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
m_dcMemory2.CreateCompatibleDC(pDc);
m_dcMemory2.SelectObject((HGDIOBJ)hBitmap);//有意:不返回旧的
ReleaseDC(pDc);

}

m_Bmpm_dcMemorym_dcMemory2 这三个是类的成员对象, 函数的这种写法,为什么可以保证gdi对象不泄露?


例子2:是群里一个人的问题

 
函数()
{

CClientDC dc(this);
//创建一个空画刷
CBrush brush (COLORREF crColor);


dc.SelectObject(brush);

//绘制一个矩形
dc.Rectangle(CRect(m_ptOrigin,point));

}

是否会泄露?是否会正确删除



[解决办法]
何为泄露啊,求教
[解决办法]
应该不会
1:
m_Bmp    m_dcMemory    m_dcMemory2是栈变量,程序结束会自动出栈。
CDC* pDc=GetDC();是堆变量,所以最后需要ReleaseDC(pDc); 
没有问题。
2:
CClientDC的构造函数完成GetDC,解构函数完成ReleaseDC。
而CClientDC dc(this)导致dc变量是个栈变量,程序结束自动出栈完成解构。
也没有问题。
[解决办法]
例子1如果只调用1次没问题,虽然原则上要去释放,但进程主动退出了OS会自动回收掉,不存在泄漏,但如果调用多次,会有泄漏。特别的 LoadImage,MSDN上描述:The system automatically deletes these resources when the process that created them terminates;要不主动释放,会一直存在直到进程退出。Create出来的东西一般都要去释放。

例子2如果只调用1次也没什么问题,次数多了会有泄漏,正确的做法seleteobject时先保存旧的数据,用完后再selectobject回来。曾经碰到过一个问题,就是因为selectobject没有选回旧的数据,结果调用次数多了导致花屏黑屏。


[解决办法]
1. CreateCompatibleBitmap没有看到DeleteObject,CreateCompatibleDC没有看到DeleteDC
2. 需要SelectObject原来的HBRUSH
[解决办法]
用API的地方,会有泄漏,比如LoadImage,其它的都用MFC类,不会有问题。
关于例子2,肯定是没有问题的,你可以自己试一下就可以了,具体的方法就是,放一个按钮,点击一次执行一次那段代码,看GDI句柄是否会无限增加即可(任务管理器里面需要把GDI句柄选上,否则默认不显示)

热点排行