内存泄漏··实在找不到问题所在··求助下论坛

猫儿累了 2012-04-07 02:42:07
HBITMAP Copybitmap(LPRECT lprect)
{
HDC hscrdc,hmemdc;
HBITMAP hbitmap, holdbitmap;
int nx,ny,nx2,ny2;
int nwidth,nheight;
int xscrn,yscrn;
if(IsRectEmpty(lprect))
return NULL;
hscrdc=CreateDC(L"display",NULL,NULL,NULL);
hmemdc=CreateCompatibleDC(hscrdc);
nx=lprect->left;
ny=lprect->top;
nx2=lprect->right;
ny2=lprect->bottom;
xscrn = GetDeviceCaps(hscrdc, HORZRES);
yscrn = GetDeviceCaps(hscrdc, VERTRES);
if (nx < 0)
nx = 0;
if (ny < 0)
ny = 0;
if (nx2 > xscrn)
nx2 = xscrn;
if (ny2 > yscrn)
ny2 = yscrn;
nwidth = nx2 - nx;
nheight = ny2 - ny;
hbitmap = CreateCompatibleBitmap(hscrdc, nwidth, nheight);
holdbitmap = (HBITMAP)SelectObject(hmemdc, hbitmap);
BitBlt(hmemdc, 0, 0, nwidth, nheight,hscrdc, nx, ny, SRCCOPY);
hbitmap = (HBITMAP)SelectObject(hmemdc, holdbitmap);
//清除
DeleteDC(hscrdc);
DeleteDC(hmemdc);
// 返回位图句柄
return hbitmap;

}
void CJPG研究Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
using namespace Gdiplus;
/////////////////////截图并返回图像句柄///////////////////////////
LPRECT temprect;
temprect=new RECT();//使用NEW创建一个RECT对象于动态内存区中,并返回对象首地址赋给temprect变量
temprect->bottom=768;//第二点Y
temprect->left=0;//第一点X
temprect->right=1366;//第二点X
temprect->top=0;//第一点Y
Sleep(3000);
HBITMAP bm=Copybitmap(temprect);
delete temprect;
Bitmap* pBmp = Bitmap::FromHBITMAP(bm, NULL); // 从我得到的截图的句柄创建一个Bitmap,指针pBmp
DeleteObject(bm);//释放位图句柄
IStream* pStream = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pStream);
CLSID jpgClsid;
GetEncoderClsid(L"image/jpeg", &jpgClsid);
pBmp->Save(pStream, &jpgClsid);
HGLOBAL hGlobal = NULL;
GetHGlobalFromStream(pStream, &hGlobal);
DWORD daxiao=GlobalSize(hGlobal);
LPBYTE pBits = (LPBYTE)GlobalLock(hGlobal);
GlobalUnlock(hGlobal);
pStream->Release();
delete pBmp;
}

int GetImageCLSID(const WCHAR* format, CLSID* pCLSID)
{ //得到格式为format的图像文件的编码值,访问该格式图像的COM组件的GUID值保存在pCLSID中
UINT num = 0;
UINT size = 0;
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num,&size);
if(size == 0)
return FALSE; // 编码信息不可用
//分配内存
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return FALSE; // 分配失败
//获得系统中可用的编码方式的所有信息
GetImageEncoders(num, size, pImageCodecInfo);
//在可用编码信息中查找format格式是否被支持
for(UINT i = 0; i < num; ++i)
{ //MimeType:编码方式的具体描述
if( wcscmp(pImageCodecInfo[i].MimeType, format) == 0 )
{
*pCLSID = pImageCodecInfo[i].Clsid;
free(pImageCodecInfo);
return TRUE;
}
}
free(pImageCodecInfo);
return FALSE;
}





以上是一段MFC捉屏的代码,当不断点击按钮一运行OnBnClickedButton1函数···发现内存不停的升高···有时候内存又停止不动···测试过后发觉··当截图的时候与上一张图片(也就是电脑屏幕画面变化不大的时候)···内存没升高··但是当截图的画面变化了··那么我们再点按钮一的时候···内存就升高了···貌似是内存泄漏···但是代码里我又明明用了pStream->Release();其释放流对象和内存···有点怀疑是这个流的问题···大家可以复制代码去测试一下··答得好的加分啊喂····找了好久木有找出原因··在线等答案··












...全文
256 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
猫儿累了 2012-04-12
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]
百度搜一下内存泄漏你就明白了。你这个是流使用错误的经典问题
[/Quote]

被你说对了···
kyotrue 2012-04-10
  • 打赏
  • 举报
回复
排查代码的话就搜索所有的new,看delete没有。
不行的话就用3#的方法,逐段屏蔽代码
Eleven 2012-04-10
  • 打赏
  • 举报
回复
Create...DC和DeleteDC对应
Create...Bitmap和DeleteObject对应
GetDC和ReleaseDC()对应
。。。
Eleven 2012-04-10
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]
不懂,帮你顶一下,我碰到过在CPU飙升到100%的问题,没有解决
[/Quote]
死循环了吧~
anna09 2012-04-10
  • 打赏
  • 举报
回复
不懂,帮你顶一下,我碰到过在CPU飙升到100%的问题,没有解决
mm9154 2012-04-10
  • 打赏
  • 举报
回复
百度搜一下内存泄漏你就明白了。你这个是流使用错误的经典问题
Tinary3v0 2012-04-08
  • 打赏
  • 举报
回复
我当时看的就是360任务管理器,内存优化后的结果,不优化怎么能看到飙升呢?
我对IStream不了解,不然也可以帮你测测这个方面的,实在是不懂啊 呵呵
等人 呵呵
猫儿累了 2012-04-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
逐段屏蔽代码,然后定位哪个地方出错
[/Quote]

这个方法试过了不管用···让人抓狂的是···他一时内存飘升····一时又静止不动···一时又一切正常····能找到的一些共同点就是····上面代码放死循环的话···内存飘升就会更明显了··· 补充一点吧···我发觉除了我的程序之外···其他软件貌似也存在同样的内存飘升问题······发生的现象如下···内存升高很多(100K)左右··然后内存释放50K左右···然后又升高100K···如此循环的···当用一些内存优化···我用360硬件大师··优化了之后····原本进程中占90M的内存···一下子降到300K····我顿时无语了··360是不是真的这么牛B还是在骗人眼的呢?···只好继续等答案吧····5点了··就这样通宵摸索了一天···
猫儿累了 2012-04-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
内存泄漏?你是从什么地方看出来的?
内存有没有泄漏不是光从任务管理器就能断定的,你说的内存增加的情况,也可能是Windows内存管理机制引起的。
你把程序用一个死循环去运行这部分代码,如果过一天,系统还能正常使用,说明你的程序基本上没有问题了。
[/Quote]

这个我有点认同····难道是我走进了微软系统的BUG了?····其实当我一句一句的运行时候···有时候发觉pStream->Release();这句····貌似不能及时清理内存··但有时候它又清理了···
还有就是想问下CreateStreamOnHGlobal(NULL, TRUE, &pStream);
创建的内部流对象····用pStream->Release();去释放是不是正确的····总觉得问题就是出在这句·····我怀疑是不是频繁的流操作···会导致这种现象呢···然后系统就会产生一些看似内存泄漏的内存碎片区域······然后我用了360内存优化···还真清理了···实在想不明白···看来我得打电话找盖茨了··
猫儿累了 2012-04-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
测试了一下楼主的代码,问题和楼主描述基本相同。我对内存泄露的认识和楼主基本相当,都是看任务管理器。
代码放在定时器中运行一段时间后,内存会增长一部分,不是很多,但是也并不是可以容忍,毕竟多次后,内存的增加还是有一定量的。
从代码上,我能发现的问题是:
1.HBITMAP Copybitmap(LPRECT lprect)函数中,holdbitmap变量没有在return前释放:DeleteO……
[/Quote]

回答的挺好的,今天偶然发现一个问题····用了360硬件大师··也就是鲁大师啦··优化一下内存···结果我进程的内存减少了···系统运行速度又变快了····然后过一段时间··程序的内存又上去了····难道还要每次内存升上去···又手动优化一下内存····
Tinary3v0 2012-04-07
  • 打赏
  • 举报
回复
测试了一下楼主的代码,问题和楼主描述基本相同。我对内存泄露的认识和楼主基本相当,都是看任务管理器。
代码放在定时器中运行一段时间后,内存会增长一部分,不是很多,但是也并不是可以容忍,毕竟多次后,内存的增加还是有一定量的。
从代码上,我能发现的问题是:
1.HBITMAP Copybitmap(LPRECT lprect)函数中,holdbitmap变量没有在return前释放:DeleteObject( holdbitmap );
2.OnBnClickedButton1()函数中LPBYTE pBits = (LPBYTE)GlobalLock(hGlobal);一句,中声明的一个从来不用的LPBYTE pBits,如果后续没有使用,最好是直接改成:GlobalLock(hGlobal);不要再多声明一个指针。
3.using namespace Gdiplus;最好直接放到StdAfx.h中去,不要再函数中使用。这个和内存之间没有什么关系。
4.为什么像LPRECT temprect; temprect=new RECT();这样的表示方法总是出现。为什么不直接声明为RECT temprect;使用的时候使用取地址&temprect?
5.整个OnBnClickedButton1()函数中的绝大部分变量都可以从函数中抽出来,用类成员函数的方式声明,不必每次都创建,然后再销毁,影响速度又会增加内存泄露的机会。
6.你说屏幕每次变动的时候内存会增加一点,这个确实存在,但是往往一会内存又降下来了。我不是很明白,猜测一下:是不是因为Windows调色板的问题?
Windows在创建一个内存HBITMAP的时候,使用的是“动态调色板”?,虽然整个屏幕的像素点数是一直不变的,但是,调色板却会因为你颜色的差异变化而增大或变小,造成内存增加的量并不一致。
能想到的就这么多,楼主参考.
zhouzhipen 2012-04-07
  • 打赏
  • 举报
回复
内存泄漏?你是从什么地方看出来的?
内存有没有泄漏不是光从任务管理器就能断定的,你说的内存增加的情况,也可能是Windows内存管理机制引起的。
你把程序用一个死循环去运行这部分代码,如果过一天,系统还能正常使用,说明你的程序基本上没有问题了。
shn521 2012-04-07
  • 打赏
  • 举报
回复
http://blog.csdn.net/na_he/article/details/7429171
shn521 2012-04-07
  • 打赏
  • 举报
回复
逐段屏蔽代码,然后定位哪个地方出错
猫儿累了 2012-04-07
  • 打赏
  • 举报
回复
继续补充一点···要点多几次按钮1···然后慢慢地···就发觉内存有一定几率会升上去···好诡异···难道是释放流对象内存的时候···有一定几率释放失败?
猫儿累了 2012-04-07
  • 打赏
  • 举报
回复
少发了一个函数···现在补上···麻烦大家分析下原因了
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num= 0;
UINT size= 0;

ImageCodecInfo* pImageCodecInfo= NULL;

GetImageEncodersSize(&num, &size);
if(size== 0)
{
return -1;
}
pImageCodecInfo= (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo== NULL)
{
return -1;
}

GetImageEncoders(num, size, pImageCodecInfo);

for(UINT j=0; j< num; ++j)
{
if(wcscmp(pImageCodecInfo[j].MimeType, format)== 0)
{
*pClsid= pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j;
}
}

free(pImageCodecInfo);
return -1;
}

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧