请问如何释放IStream?

水经注GIS
企业官方账号
2008-12-20 11:04:21
我循环调用以下函数,结果内存直线上涨,后来调试跟踪后发现在执行“pIStream->Release();”这句代码时,内存没有减少,请问是什么原因呢?
=======================
//从Bitmap 生成 Void * buffer
void* CAdo::CreateBufferFromBitmap(Bitmap* pBitmap,UINT& nBufferSize)
{
CLSID clsid;
int clsidResult = GetImageCLSID(L"image/jpeg",&clsid);
LPSTREAM pIStream = NULL;
CreateStreamOnHGlobal(NULL, TRUE, &pIStream);
pBitmap->Save(pIStream,&clsid);

STATSTG statstg;
memset (&statstg, 0, sizeof(statstg));
pIStream->Stat(&statstg, STATFLAG_NONAME);
void* pSaveBuffer = malloc(statstg.cbSize.LowPart);

LARGE_INTEGER dlibMove = { 0 };
pIStream->Seek(dlibMove,STREAM_SEEK_SET,NULL);
pIStream->Read(pSaveBuffer,statstg.cbSize.LowPart,NULL);

pIStream->Release();
pIStream = NULL;

nBufferSize = statstg.cbSize.LowPart;

return pSaveBuffer;
}
...全文
482 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
水经注GIS 2008-12-20
  • 打赏
  • 举报
回复
找到问题了,varBLOB.parray没有用SafeArrayDestroy(varBLOB.parray);来释放!非常感谢wangjia184的热必帮助,之前跟踪到pIStream->Release()没有发现内存减少,一直误认为是没有释放,呵呵!
CodeProject-Jerry 2008-12-20
  • 打赏
  • 举报
回复
你的代码是确定了有内存泄露 还是说
只是在循环的时候内存使用攀升?

用BoundsCheck 或者 GDIPlush.h的方式查查有没有GDI+的内存泄露

如果没有内存泄露,只是循环中的内存使用量不断上升,

那么你改写一下代码

pRecordset 《-- 可能是这个在循环中造成。

可以改成,每次都新开一个pRecordset ,用完就释放试试
水经注GIS 2008-12-20
  • 打赏
  • 举报
回复
//调用代码如下
===========================
CFileFind finder;
finder.FindFile("E:\\人口免冠照\\*.*");
CAdo * pAdo = new CAdo();
pAdo->InitAdo("localhost","sa","sa","photo",FALSE);
if (pAdo->Connection() == FALSE)
{
return;
}

CString strTableName = "photo_1";
UINT nSize;CString strSql="";
CString strFilePath = "";
Bitmap * pBitmap = NULL;
CString strFileName = "";

BOOL bTrue = TRUE;
int nCount = 0;

strSql.Format("Select * From %s",strTableName);
_RecordsetPtr pRecordset = pAdo->GetRecordset(strSql);
while (bTrue)
{
bTrue = finder.FindNextFile();
strFilePath = finder.GetFilePath();
strFileName = finder.GetFileName();
if (finder.IsDots() || strFileName.Left(1) != "t")
{
continue;
}

strFileName = strFileName.Left(strFileName.GetLength() - 4);

int nRow,nCol;
GetRowCol(strFileName,nRow,nCol);

pRecordset->AddNew();
pBitmap = Bitmap::FromFile(strFilePath.AllocSysString());
BYTE * pVoid = (BYTE*)pAdo->CreateBufferFromBitmap(pBitmap,nSize);

if (pVoid != NULL)
{
pAdo->AddBLOBValue(pRecordset,_variant_t("data"),pVoid,nSize , FALSE);
}

free(pVoid);
pVoid = NULL;
delete pBitmap;

nCount++;
}

pRecordset->Update();
pRecordset->Close();

AfxMessageBox("导入完成!");
CodeProject-Jerry 2008-12-20
  • 打赏
  • 举报
回复
CreateStreamOnHGlobal 第2个参数设置为FALSE

GlobalFree那个 hGlobal试试
水经注GIS 2008-12-20
  • 打赏
  • 举报
回复
完整代码,如下
==========================
CFileFind finder;
finder.FindFile("E:\\人口免冠照\\*.*");
CAdo * pAdo = new CAdo();
pAdo->InitAdo("localhost","sa","sa","photo",FALSE);
if (pAdo->Connection() == FALSE)
{
return;
}

CString strTableName = "photo_1";
UINT nSize;CString strSql="";
CString strFilePath = "";
Bitmap * pBitmap = NULL;
CString strFileName = "";

BOOL bTrue = TRUE;
int nCount = 0;

strSql.Format("Select * From %s",strTableName);
_RecordsetPtr pRecordset = pAdo->GetRecordset(strSql);
while (bTrue)
{
bTrue = finder.FindNextFile();
strFilePath = finder.GetFilePath();
strFileName = finder.GetFileName();
if (finder.IsDots() || strFileName.Left(1) != "t")
{
continue;
}

strFileName = strFileName.Left(strFileName.GetLength() - 4);

int nRow,nCol;
GetRowCol(strFileName,nRow,nCol);

pRecordset->AddNew();
pBitmap = Bitmap::FromFile(strFilePath.AllocSysString());
BYTE * pVoid = (BYTE*)pAdo->CreateBufferFromBitmap(pBitmap,nSize);

if (pVoid != NULL)
{
pAdo->AddBLOBValue(pRecordset,_variant_t("data"),pVoid,nSize , FALSE);
}

free(pVoid);
pVoid = NULL;
delete pBitmap;

nCount++;
}

pRecordset->Update();
pRecordset->Close();

AfxMessageBox("导入完成!");
水经注GIS 2008-12-20
  • 打赏
  • 举报
回复
void* pSaveBuffer = malloc(statstg.cbSize.LowPart);
这个在函数外部是释放了的。
free(pSaveBuffer);
pSaveBuffer = NULL; //当执行到这句时,看到内存明显释放!
CodeProject-Jerry 2008-12-20
  • 打赏
  • 举报
回复
我觉得最有可能的地方是2个


Bitmap* pBitmap
以及
pSaveBuffer


如果Bitmap你是在Stack上申请的内存空间, 那么它的作用域是否保证它的析构被即时调用?
pSaveBuffer 这个是不是用完了马上释放?

你的循环是怎么写的, 记得每次循环结束马上释放资源, 不要等到循环全部结束再去释放资源
CodeProject-Jerry 2008-12-20
  • 打赏
  • 举报
回复
CreateStreamOnHGlobal 第2个参数设置为TRUE
那么Release的时候就会释放啊


void* pSaveBuffer = malloc(statstg.cbSize.LowPart);
你这个传递出去释放没有??

16,471

社区成员

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

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

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