恳请高手进!!!!有关图像显示,重会时出现内存使用量不断变大

xuchenhua 2009-10-21 09:56:00
我的问题是这样的,我把位图存到Access中在从数据库中读出来,让好几张位图显示在视图中,视图是以CScrollView为基类的视图。功能是实现了但是问题出来了。当我托动视图的滚动条时,我每托动一次后查看任务管理器中的内存使用量,发现内存使用量在不断的变大。我想可能是视图窗口发生重会时内存使用量在不断的变大。请问怎样解决这个问题啊?
下面是我实现从数据库中取出位图再让位图显示在视图窗口上的代码,请大家看看问题出现在哪,是不是哪个资源用完后没关啊?请大家指点指点啊!
void CPrintView::OnDraw(CDC* pDC)
{
CPrintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
int nPageNumber=pInfo->m_nCurPage;
ADO m_Ado;
m_Ado.OnInitADOConn();//连接数据库
CString SQL;
///////////////////////////////////////////////////////////////// 表示把相片插入到相应的学号的那行记录中
if (report.all)
{
SQL.Format("select * from xuyuanxinxibaobiao order by 学号 asc");
m_Ado.m_pRecordset = m_Ado.OpenRecordset(SQL);//打开记录集
}
else
{
SQL= "select * from xuyuanxinxibaobiao";
m_Ado.m_pRecordset = m_Ado.OpenRecordset(SQL);
CString str;
str.Format("%s = '%s'",report.strField, report.neirong);//设置查询字符串
m_Ado.m_pRecordset->Filter = (_bstr_t)str;//进行查询
m_Ado.m_pRecordset->Requery(0);//用查询结果更新当前记录集
}
int x=1;
while(!m_Ado.m_pRecordset->adoEOF)
{
for(int i=0;i<7;i++)
{
if(nPageNumber==x)
{
HBITMAP m_hBitmap;
//读取图像字段的实际大小
long lDataSize = m_Ado.m_pRecordset ->GetFields()->GetItem("照片")->ActualSize;
char *m_pBuffer; //定义缓冲变量
if(lDataSize > 0)
{
//从图像字段中读取数据到varBLOB中
_variant_t varBLOB;
varBLOB =m_Ado.m_pRecordset ->GetFields()->GetItem("照片")->GetChunk(lDataSize);
if(varBLOB.vt == (VT_ARRAY | VT_UI1))//指定varBLOB中因素的数据类型为无符号字符型
{
if(m_pBuffer = new char[lDataSize+1]) //分配必要的存储空间
{
char *pBuf = NULL;
SafeArrayAccessData(varBLOB.parray,(void **)&pBuf);//重新装载数据,得一个指针给pBuf
memcpy(m_pBuffer,pBuf,lDataSize); ///复制数据到缓冲区m_pBuffer
SafeArrayUnaccessData (varBLOB.parray);// 又把刚才装载的数据给解开了。
//将数据转换为HBITMAP格式
LPSTR hDIB;
LPVOID lpDIBBits;
BITMAPFILEHEADER bmfHeader; //用于保存BMP文件头信息,包括类型、大小、位移量等
DWORD bmfHeaderLen; //保存文件头的长度
bmfHeaderLen = sizeof(bmfHeader); //读取文件头的长度
//将m_pBuffer中文件头复制到bmfHeader中
strncpy((LPSTR)&bmfHeader, (LPSTR)m_pBuffer, bmfHeaderLen);
if (bmfHeader.bfType != (*(WORD*)"BM")) //如果文件类型不对,则返回
{
MessageBox("BMP文件格式不准确");
return;
}
hDIB = m_pBuffer + bmfHeaderLen; //将指针移至文件头后面
//读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFOHEADER对象
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB;
//读取BMP文件的图像数据,包括坐标及颜色格式等信息到BITMAPINFO对象
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
//根据bfOffBits属性将指针移至文件头后
lpDIBBits = (m_pBuffer) + ((BITMAPFILEHEADER *)m_pBuffer)->bfOffBits;
CClientDC dc(this); //生成一个与当前窗口相关的CClientDC,用于管理输出设置
//生成DIBitmap数据

m_hBitmap = CreateDIBitmap(dc.m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);
}
}
}
if(m_hBitmap != NULL)
{
CDC memdc;
memdc.CreateCompatibleDC( pDC );// 创建一个设备上下文来记忆上面的设备上下文。也是与m_pictureshow相兼容的设备上下文
memdc.SelectObject(m_hBitmap);// 把设备上下文给m_hBitmap。也就是设备上下文中存储了m_hBitmap。
BITMAP bmp;
GetObject(m_hBitmap,sizeof(bmp),&bmp);//得到m_hBitmap的信息
pDC->StretchBlt((int)(37*rate.x),(int)((60+150*i)*rate.y),(int)(124*rate.x),(int)(119*rate.y),&memdc,0,0,
bmp.bmWidth,bmp.bmHeight,SRCCOPY); // 把源设备上下文的m_hBitmap复制到PCD里
memdc.DeleteDC();
}
m_Ado.m_pRecordset->MoveNext();
if ( !m_Ado.m_pRecordset->adoEOF )
{/*m_Ado.m_pRecordset->MoveNext();*/}//将记录集指针移动到下一条记录
else
{ m_Ado.CloseRecordset();
m_Ado.CloseConn();//断开数据库连接
return;
}
}
x++;
}
m_Ado.CloseRecordset();
m_Ado.CloseConn();//断开数据库连接
...全文
183 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
liumenghappy 2009-10-22
  • 打赏
  • 举报
回复
你先看看哪个有内存泄露,方法如下:
按F5,在调试状态下运行,程序退出后在“输出窗口”可以看到有无内存泄露出现,例如:
Detected memory leaks!
Dumping objects ->
C:PROGRAM FILESVISUAL STUDIOMyProjectsleaktestleaktest.cpp(20) : {18} normal block at 0x00780E80, 64 bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD CD
Object dump complete.
然后再逐个释放就行了
YANGJINLOVEYOU 2009-10-22
  • 打赏
  • 举报
回复
肯定是有申请的资源还没有释放
fandh 2009-10-22
  • 打赏
  • 举报
回复
是的!
xuchenhua 2009-10-22
  • 打赏
  • 举报
回复
m_hBitmap = CreateDIBitmap(dc.m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);这句话还要
将这memdc.SelectObject(m_hBitmap);改为HBITMAP  oldbmp = memdc.SelectObject(m_hBitmap);吗?
然后再memdc.SelectObject(oldbmp );DeleteObject(m_hBitmap);
memdc.DeleteDC();释放。是这个意思吗?
xuchenhua 2009-10-22
  • 打赏
  • 举报
回复
DeleteObject(m_hBitmap);这样怎么不能释放吗?为什么啊?
xuchenhua 2009-10-22
  • 打赏
  • 举报
回复
请问我哪样为什么释放不了啊?
我中午试试,现在没在电脑旁边!
fandh 2009-10-22
  • 打赏
  • 举报
回复
HBITMAP oldbmp = memdc.SelectObject(m_hBitmap);// 把设备上下文给m_hBitmap。也就是设备上下文中存储了m_hBitmap
//下面是使用memdc,用完后,再加下面的代码
memdc.SelectObject(oldbmp );// 将m_hBitmap解除与设备的关联,不然删除不了
DeleteObject(m_hBitmap);
memdc.DeleteDC();
fandh 2009-10-22
  • 打赏
  • 举报
回复
varBLOB要不要释放啊?

这个不用!
fandh 2009-10-22
  • 打赏
  • 举报
回复
m_hBitmap = CreateDIBitmap(dc.m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);
这个m_hBitmap创建后,也要删除:DeleteObject(m_hBitmap);


这样改:
HBITMAP oldbmp = memdc.SelectObject(m_hBitmap);// 把设备上下文给m_hBitmap。也就是设备上下文中存储了m_hBitmap
//下面是使用memdc,用完后,再加下面的代码
memdc.SelectObject(oldbmp );// 将m_hBitmap解除与设备的关联,不然删除不了
DeleteObject(m_hBitmap);


这样就行了!
xuchenhua 2009-10-22
  • 打赏
  • 举报
回复
请问  bmp varBLOB要不要释放啊?
hufen2740 2009-10-22
  • 打赏
  • 举报
回复
!!!!
fandh 2009-10-22
  • 打赏
  • 举报
回复
delete m_pBuffer;
m_pBuffer = NULL;

要改成:
delete []m_pBuffer;
m_pBuffer = NULL;
xuchenhua 2009-10-22
  • 打赏
  • 举报
回复
内存泄漏谁来解答!!!!
fandh 2009-10-22
  • 打赏
  • 举报
回复
楼主搞定了?
muzizongheng 2009-10-21
  • 打赏
  • 举报
回复
如果还有内存泄露, 肯定还有其他地方啊. 刚才的那些肯定有内存泄露.
xuchenhua 2009-10-21
  • 打赏
  • 举报
回复
?或许是其他的原因
xuchenhua 2009-10-21
  • 打赏
  • 举报
回复
请问 bmp怎么释放,还有varBLOB怎么释放,或许还有其他的?
xuchenhua 2009-10-21
  • 打赏
  • 举报
回复
是不是还有其他的没释放啊,还是有变大!
muzizongheng 2009-10-21
  • 打赏
  • 举报
回复
m_hBitmap
DeleteObject(m_hBitmap);
muzizongheng 2009-10-21
  • 打赏
  • 举报
回复
delete m_pBuffer;
m_pBuffer = NULL;
加载更多回复(4)

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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