小弟我现在有以下这一段代码,能正常运行,也能得到想要的结果,但是不知道这段代码多次运行是否会造成
资源泄露,或者有一些隐患在?有请各位有空的高手指点指点? 该函数如下:
//根据这四个参数的内容来生成BMP格式的数据.
//生成的图片格式是 258*128,是黑白两色的BMP图
bool makedisplaybmp(int nThisPrice,int nAcuPrice,int vipScore,CString strVipCode)
{
//生成图片 CDC memDC; //主窗体其实是隐藏的,也疑惑这句调用不知道是否合适.
CWnd *pWnd=AfxGetMainWnd();
CDC *pDC=pWnd->GetDC(); CFont fontBlack;
CString strMsg;
CBitmap bmpSave;
BITMAP bmpInfo;
LOGFONT lfBlack;
LOGBRUSH lbBack; //背景色
CBrush bhBack;
unsigned short usTmp;
int nLen,nWidth,nHeight; BITMAPFILEHEADER fileHead; memset(&lfBlack,0,sizeof(lfBlack)); //字体是黑色
lfBlack.lfHeight =24;
strcpy(lfBlack.lfFaceName,_T("宋体"));
lfBlack.lfWeight =FW_BOLD;
fontBlack.CreateFontIndirect(&lfBlack); lbBack.lbColor =RGB(255,255,255); //背景色是白色
lbBack.lbStyle =BS_SOLID;
bhBack.CreateBrushIndirect(&lbBack); bmpSave.CreateBitmap(256,128,1,1,NULL); //宽度256,高度是128
memDC.CreateCompatibleDC(pDC); CBitmap *pOldBmp=memDC.SelectObject(&bmpSave);
CFont *pOldFont=memDC.SelectObject(&fontBlack);
CBrush *pOldBrush=memDC.SelectObject(&bhBack); CRect rect;
rect.top =0;
rect.bottom =129;
rect.left =0;
rect.right =257;
memDC.FillRect(&rect,&bhBack); //背景色是白色 //输出图片的内容
//会员卡 和积分 strMsg=_T("多谢惠顾!");
memDC.TextOut(64,4,strMsg); strMsg.Format("本次金额:%d元",nThisPrice);
memDC.TextOut(8,30,strMsg); //累计金额
strMsg.Format("累计金额:%d元",nAcuPrice);
memDC.TextOut(8,52,strMsg); strMsg.Format("会员卡号:%s",strVipCode);
memDC.TextOut(8,74,strMsg); strMsg.Format("累计积分:%d",vipScore);
memDC.TextOut(8,96,strMsg);
bmpSave.GetBitmap(&bmpInfo);
nWidth=bmpInfo.bmWidth;
nHeight=bmpInfo.bmHeight;
nLen=bmpInfo.bmWidthBytes *nHeight;
unsigned char pData[32*160]; //保存bmp图的数据,因为宽度是256,所以32个 Byte,高度应该128,现在160是留多一些位置
memset(pData,0,nLen); BITMAPINFO *pBITMAPINFO=(BITMAPINFO*)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+2*sizeof (RGBQUAD));
pBITMAPINFO->bmiHeader.biBitCount =1;
pBITMAPINFO->bmiHeader.biClrImportant=0;
pBITMAPINFO->bmiHeader.biCompression =0;
pBITMAPINFO->bmiHeader.biHeight =nHeight;
pBITMAPINFO->bmiHeader.biWidth =nWidth;
pBITMAPINFO->bmiHeader.biPlanes =1;
pBITMAPINFO->bmiHeader.biSize =sizeof(BITMAPINFOHEADER);
pBITMAPINFO->bmiHeader.biSizeImage =nLen;
pBITMAPINFO->bmiHeader.biXPelsPerMeter =0;
pBITMAPINFO->bmiHeader.biYPelsPerMeter =0;
//pBITMAPINFO->bmiHeader.biClrImportant =0;
//pBITMAPINFO->bmiHeader.biClrUsed =2;
//获得bmp图的 数据,并保存在 pData数组中
GetDIBits(memDC.m_hDC,bmpSave,0,nHeight,pData,pBITMAPINFO,DIB_RGB_COLORS);
//最后的动作,清除一些资源,也是我有疑虑的地方,不知道单清除这三个资源是否合适.
memDC.DeleteDC();
pWnd->ReleaseDC(pDC);
LocalFree(pBITMAPINFO); }
资源泄露,或者有一些隐患在?有请各位有空的高手指点指点? 该函数如下:
//根据这四个参数的内容来生成BMP格式的数据.
//生成的图片格式是 258*128,是黑白两色的BMP图
bool makedisplaybmp(int nThisPrice,int nAcuPrice,int vipScore,CString strVipCode)
{
//生成图片 CDC memDC; //主窗体其实是隐藏的,也疑惑这句调用不知道是否合适.
CWnd *pWnd=AfxGetMainWnd();
CDC *pDC=pWnd->GetDC(); CFont fontBlack;
CString strMsg;
CBitmap bmpSave;
BITMAP bmpInfo;
LOGFONT lfBlack;
LOGBRUSH lbBack; //背景色
CBrush bhBack;
unsigned short usTmp;
int nLen,nWidth,nHeight; BITMAPFILEHEADER fileHead; memset(&lfBlack,0,sizeof(lfBlack)); //字体是黑色
lfBlack.lfHeight =24;
strcpy(lfBlack.lfFaceName,_T("宋体"));
lfBlack.lfWeight =FW_BOLD;
fontBlack.CreateFontIndirect(&lfBlack); lbBack.lbColor =RGB(255,255,255); //背景色是白色
lbBack.lbStyle =BS_SOLID;
bhBack.CreateBrushIndirect(&lbBack); bmpSave.CreateBitmap(256,128,1,1,NULL); //宽度256,高度是128
memDC.CreateCompatibleDC(pDC); CBitmap *pOldBmp=memDC.SelectObject(&bmpSave);
CFont *pOldFont=memDC.SelectObject(&fontBlack);
CBrush *pOldBrush=memDC.SelectObject(&bhBack); CRect rect;
rect.top =0;
rect.bottom =129;
rect.left =0;
rect.right =257;
memDC.FillRect(&rect,&bhBack); //背景色是白色 //输出图片的内容
//会员卡 和积分 strMsg=_T("多谢惠顾!");
memDC.TextOut(64,4,strMsg); strMsg.Format("本次金额:%d元",nThisPrice);
memDC.TextOut(8,30,strMsg); //累计金额
strMsg.Format("累计金额:%d元",nAcuPrice);
memDC.TextOut(8,52,strMsg); strMsg.Format("会员卡号:%s",strVipCode);
memDC.TextOut(8,74,strMsg); strMsg.Format("累计积分:%d",vipScore);
memDC.TextOut(8,96,strMsg);
bmpSave.GetBitmap(&bmpInfo);
nWidth=bmpInfo.bmWidth;
nHeight=bmpInfo.bmHeight;
nLen=bmpInfo.bmWidthBytes *nHeight;
unsigned char pData[32*160]; //保存bmp图的数据,因为宽度是256,所以32个 Byte,高度应该128,现在160是留多一些位置
memset(pData,0,nLen); BITMAPINFO *pBITMAPINFO=(BITMAPINFO*)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+2*sizeof (RGBQUAD));
pBITMAPINFO->bmiHeader.biBitCount =1;
pBITMAPINFO->bmiHeader.biClrImportant=0;
pBITMAPINFO->bmiHeader.biCompression =0;
pBITMAPINFO->bmiHeader.biHeight =nHeight;
pBITMAPINFO->bmiHeader.biWidth =nWidth;
pBITMAPINFO->bmiHeader.biPlanes =1;
pBITMAPINFO->bmiHeader.biSize =sizeof(BITMAPINFOHEADER);
pBITMAPINFO->bmiHeader.biSizeImage =nLen;
pBITMAPINFO->bmiHeader.biXPelsPerMeter =0;
pBITMAPINFO->bmiHeader.biYPelsPerMeter =0;
//pBITMAPINFO->bmiHeader.biClrImportant =0;
//pBITMAPINFO->bmiHeader.biClrUsed =2;
//获得bmp图的 数据,并保存在 pData数组中
GetDIBits(memDC.m_hDC,bmpSave,0,nHeight,pData,pBITMAPINFO,DIB_RGB_COLORS);
//最后的动作,清除一些资源,也是我有疑虑的地方,不知道单清除这三个资源是否合适.
memDC.DeleteDC();
pWnd->ReleaseDC(pDC);
LocalFree(pBITMAPINFO); }
解决方案 »
- activeX控件处理后的图片怎样显示在IE上
- WEBBROWSER在里面点击链接并在新窗口中打开时,怎么使用默认浏览器打开?
- tab control控件子对话框中不能创建CListCtrl对象
- MFC中,自定义类如何访问View类中的变量或函数?
- HOOK文件打开问题:现在代码能够在TXT文件进行验证,如何能够在其他类型文件打开时也进行验证?
- 函数注册
- 完成端口模型中如何控制客户端的连接时间。
- 在TreeCtrl失去焦点时,如何获取当前选中的节点值
- 了解内存的泄漏。
- 求助,串口通信OnComm()函数里面的数据处理
- 图像背景上画线,文字的问题,急
- 问一问虚拟地址的概念问题,一直弄的不是很明白!请高手指点!分不多请见谅!
ps:别忘了从任务管理器里的查看菜单下的选择列,把资源选出来观察。
你可以在调用之前和之后加个断点,察看你进程使用GDI情况,然后再继续运行察看GDI对象的变化。
这样应该可以知道有没有泄露,以及具体泄露了什么对象。
利用任务管理器查看GDI对象,运行了十多次,发现没有增加.奇怪了,各位看看,还有没有什么招数?
makedisplaybmp用for循环一直执行,同时这个时候观察任务管理器,不是退出进程重新运行。
如果这样资源依然保持稳定的话,那就基本没有资源泄漏的问题了。
应该对其进行还原,选出你选入的所有gdi对象(位图、刷子、字体),这样才是安全的
memDC.SelectObject(pOldBmp);
memDC.SelectObject(pOldFont);
memDC.SelectObject(pOldBrush); MFC的gdi类的析构函数会自行进行deleteobject等操作,所以memDC.DeleteDC(); 并不是必须的
#ifdef _DEBUG
class CGuiResourceCheck
{
int m_gdi, m_user;
public:
CGuiResourceCheck()
{
m_gdi = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
m_user = GetGuiResources(GetCurrentProcess(), GR_USEROBJECTS);
} ~CGuiResourceCheck()
{
int gdi = GetGuiResources(GetCurrentProcess(), GR_GDIOBJECTS);
int user = GetGuiResources(GetCurrentProcess(), GR_USEROBJECTS); if (gdi != m_gdi || user!=m_user)
{
TRACE(_T("Resouce Difference: GDI_Ojects(%d -> %d), USER_Objects(%d -> %d)\n"), m_gdi, gdi, m_user, user);
}
}
};
#endif用法:
bool makedisplaybmp(int nThisPrice,int nAcuPrice,int vipScore,CString strVipCode)
{
#ifdef _DEBUG
CGuiResourceCheck rescheck;
#endif
......
}
也没发现过内存泄漏的问题。仔细check一下,不要依赖于第三方工具。