2015-10-05 69 views
1

我有功能,其产生Gdiplus::BitmapC++从存储器加载位图 - 存储器泄漏

Bitmap *LoadBitmapT(const unsigned char* fileBuffer, size_t length) { 
    HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, length); 
    BYTE* pmem = (BYTE*)GlobalLock(m_hMem); 
    memcpy(pmem, fileBuffer, length); 

    IStream* pstm; 
    CreateStreamOnHGlobal(m_hMem, FALSE, &pstm); 

    Gdiplus::Bitmap *bitmap = Gdiplus::Bitmap::FromStream(pstm, FALSE); 

    GlobalUnlock(m_hMem); 
    pstm->Release(); 
    return bitmap; 
} 

正如您所看到的,由于GlobalAlloc(),显示内存泄漏。

当我尝试使用它GlobalFree(m_hmem)我解决了问题,内存泄漏消失。但我拉伸而获得的位图在其他功能使用此代码:

Graphics graphics(hdc); 
graphics.DrawImage(bitmap, ....); 

,当我不使用GlobalFree(),画图像是正确的。但是,当我使用提到的功能,比我失去正确的形象,它是像蓝屏的形象。

比我尽量节省的m_hMem指针和位图绘制后打电话GlobalFree()。所以,这是好的。但我需要使用旋转获取的位图,所以当我打电话bitMap->RotateFlip(RotateNoneFlipX);比内存泄漏再次出现。在位图中手动更改像素的某种颜色会产生相同的行为。

所以,我怎样才能释放内存的这一形象和正确绘制此图像。我需要它,因为我定期绘制大量图像,因此分配了大量内存,然后程序崩溃。

编辑

我试过这段代码:

Bitmap *LoadBitmapT(const unsigned char* fileBuffer, size_t length) { 
    HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, length); 
    BYTE* pmem = (BYTE*)GlobalLock(m_hMem); 
    memcpy(pmem, fileBuffer, length); 

    IStream* pstm; 
    CreateStreamOnHGlobal(m_hMem, FALSE, &pstm); 

    Gdiplus::Bitmap *bitmap = Gdiplus::Bitmap::FromStream(pstm, FALSE); 
    GlobalUnlock(m_hMem); 
    pstm->Release(); 

    GlobalFree(m_hMem); 

    return NULL; 
} 

在此之后,当我在看任务管理器,比我看到该内存不增加。

当我给bitmap->RotateFlip(RotateNoneFlipX);Gdiplus::Bitmap *bitmap = Gdiplus::Bitmap::FromStream(pstm, FALSE);和代码是相同的,但只有这一行被添加,比内存在增加。

+0

*所以,我怎样才能释放内存的这一形象和正确绘制这个图片* - 复制的图像数据在其他地方,也许在磁盘上?否则,删除内存意味着删除数据。您无法处理已删除的数据。通常,使用位图的最后一个实体是知道什么时候删除数据的实体,因此您不应该像这样删除数据。 – PaulMcKenzie

+0

我无法将其写入磁盘。我可以有这样的用例:从内存中加载它,用graphics.drawImage绘制它,然后当我想绘制另一个图像,而不是从内存中删除旧内存,所以没有内存泄漏。这适用于我,但如果我调用'bitMap-> RotateFlip(RotateNoneFlipX)''或类似的东西,比我不知道为什么时调用'GlobalFree'没有任何东西被释放。 –

+0

重新设计您的应用程序以了解安全删除内存的时间,地点以及何时是* actual *时间。说实话,你似乎没有想到它。 – PaulMcKenzie

回答

2

我找到答案。

此代码重新分配的一切是正确的。

HGLOBAL m_hMem = GlobalAlloc(GMEM_FIXED, length); 
BYTE* pmem = (BYTE*)GlobalLock(m_hMem); 
memcpy(pmem, fileBuffer, length); 

IStream* pstm; 
CreateStreamOnHGlobal(m_hMem, FALSE, &pstm); 

Gdiplus::Bitmap *bitmap = Gdiplus::Bitmap::FromStream(pstm, FALSE); 
pstm->Release(); 

GlobalUnlock(m_hMem); 

bitmap->RotateFlip(RotateNoneFlipX); 

delete bitmap; 
GlobalFree(m_hMem); 

需要按正确顺序进行调用。因此,首先删除位图,然后GlobalFree