解决CimageList内存泄露

由于项目需要,程序界面中要实现了一个缩略图显示控件,从CodeProject上查找到了一个类似的例子(原标题为:Showing the Image file thumbnail view in ListView control using VC++ 6.0 By Karpaga Rajan.),修改了一下,其中源代码中加入图片的代码如下:

 

// 查找某个文件夹下的图片文件(假如全是BMP

HBITMAP hBitmap = LoadPicture( finder.GetFilePath() );

 

if ( hBitmap != NULL )

{

int nItem = GetItemCount();

 

CBitmap *pBitmap = new CBitmap();

pBitmap->Attach( hBitmap );

 

int nImage = m_ImageList.Add( pBitmap, RGB( 255, 255, 255 ) );

InsertItem( nItem, finder.GetFileTitle(), nImage );

}

 

第一次写完后,就很郁闷,上面new了一个CBitmap,却没有在任何地方delete,今天决定解决程序中的内存泄露问题,所以就找到了这块,原本以为CImageList会提供一个让人很愉快的解决方案,不过看了下它的成员函数,这才发现没那么容易。

 

第一次尝试:加入DeleteImageList

在构的CListCtrl析构函数中加入 m_cImageList.DeleteImageList,然后将内存泄露的输出信息保存为TXT文件,用UE对比了一个,还是没有解决


第二次尝试:重组一个CBitmap*

既然CImageList.Add时加入的是一个CBitmap*,而通过调用CImageList::GetImageInfo就可能取得某一项的Info,那个结构体中就有HBITMAP,好,我得到了HBITMAP,就可以借由CBitmap::FromHanle来得到这个指针,然后DeleteObject,再delete,结构当我再次查看泄露信息时,结果仍然是失败。

第三次尝试:借用指针

既然CImageList::Add的时候存放的是个指针,我就可以用外部指针来持有,这样两个指针指向同一个对象,只要小心设计,不就可以解决了?由于CImageList中加入了很多图片(我的测试用例是38BMP),这样我就需要用集合类来存储指针。

 

typedef CArray< CBitmap*, CBitmap* > CBitmapArray;

 

// 查找某个文件夹下的图片文件(假如全是BMP

HBITMAP hBitmap = LoadPicture( finder.GetFilePath() );

 

if ( hBitmap != NULL )

{

int nItem = GetItemCount();

 

CBitmap *pBitmap = new CBitmap();

pBitmap->Attach( hBitmap );

 

m_arrBitmaps.Add( pBitmap );

 

int nImage = m_ImageList.Add( pBitmap, RGB( 255, 255, 255 ) );

InsertItem( nItem, finder.GetFileTitle(), nImage );

}

看到了吧,现在有了刚才new出来的指针的集合对象,就可以在重新载入缩略图或退出实例时将数组遍历一次,然后个个delete,再一看,泄露没了。

提示:从图中可以看到,每两行描述了一个内存泄露,我用

最末行 - 最初行 + 1 / 2

获取结果为:38

然后打开图片目录,全选一看,呵,还真38个文件。

 

这是用UE比较的结果,

左边为泄露图

右边为使用方法三后的无泄露图。

posted @ 2007-08-04 12:44  glimix  阅读(1093)  评论(1编辑  收藏  举报