2015-10-05 40 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