2012-09-12 62 views
1

請在使用FreeImage加載位圖後,幫我清理我的堆。 莫名其妙 delete[] data; 原因_ASSERTE(_CrtIsValidHeapPointer(pUserData))斷言,我找不到如何解決它,而不是評論此行。會有內存泄漏嗎? 任何幫助和解釋將不勝感激!FreeImage刪除[]位圖數據失敗

在引擎收錄全碼:http://pastebin.com/dWxz0tjM

的Visual Studio 2012的解決方案(與巨大的FreeImage靜態庫):http://rghost.ru/40322357(15.7兆字節!)

全部代碼在這裏:

#include <iostream> 

// FreeImage static linkage 
#define FREEIMAGE_LIB 
#include "FreeImage/FreeImage.h" 
#include "FreeImage/Utilities.h" 
#pragma comment(lib, "FreeImage/FreeImaged.lib") 

using namespace std; 

static const wchar_t* sk_Filename = L"Test.tga"; 

// Error handler to use in callback 
void FreeImageErrorHandler(FREE_IMAGE_FORMAT fif, const char *msg) 
{ 
    char buf[1024]; 
    sprintf_s(buf, 1024, "Error: %s", FreeImage_GetFormatFromFIF(fif)); 

    cout << buf; 
} 


// Bitmap loader from FreeImage samples 
FIBITMAP* GenericLoaderU(const wchar_t* lpszPathName, int flag) 
{ 
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN; 

    fif = FreeImage_GetFileTypeU(lpszPathName, 0); 
    if(fif == FIF_UNKNOWN) 
    { 
     fif = FreeImage_GetFIFFromFilenameU(lpszPathName); 
    } 

    if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) 
    { 
     FIBITMAP *dib = FreeImage_LoadU(fif, lpszPathName, flag); 
     return dib; 
    } 
    return NULL; 
} 

// Function gets filename and returns bitmap data array, its size and bits per pixel 
void GetData(const wchar_t* szFilename, unsigned char* data, unsigned int& width, unsigned int& height, unsigned int& bpp) 
{ 
    FIBITMAP* src = GenericLoaderU(szFilename, 0); 

    if(src == 0) 
     return; 

    FIBITMAP* src32 = FreeImage_ConvertTo32Bits(src); 
    FreeImage_Unload(src); 

    // Get picture info 
    width = FreeImage_GetWidth(src32); 
    height = FreeImage_GetHeight(src32); 
    bpp = FreeImage_GetBPP(src32); 
    unsigned int scan_width = width * bpp/8; 

    if((width == 0) || (height == 0) || (bpp == 0)) 
     return; 


    memset(data, 0, height * scan_width); 
    SwapRedBlue32(src32); // Convert BGR to RGB 

    // Get bitmap data 
    FreeImage_ConvertToRawBits(data, src32, scan_width, bpp, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, TRUE); 

    FreeImage_Unload(src32); 
    return; 
} 

int main() 
{ 
    FreeImage_Initialise(); 
    FreeImage_SetOutputMessage(FreeImageErrorHandler); 

    //Creating bitmap data array (size is unknown here) 
    unsigned char* data = new unsigned char[]; 
    unsigned int width(0), height(0), bpp(0); 

    // Loading data here 
    GetData(sk_Filename, data, width, height, bpp); 

    //Using data here 
    cout << width << "x" << height << "x" << bpp << endl; 
    for (unsigned int i = 0; i < width * height * bpp/8;) 
    { 
     cout << "(" 
     << (unsigned int)data[i] << ", " 
     << (unsigned int)data[i+1] << ", " 
     << (unsigned int)data[i+2] << ", " 
     << (unsigned int)data[i+3] << ")" 
     << endl; 

     i += 4; 
    } 
    cout << endl; 

    //Cleanup 
    delete[] data; // <-- Breaks with _ASSERTE(_CrtIsValidHeapPointer(pUserData)); 
        // What's wrong here? 

    system("pause"); 

    return 0; 
} 

---編輯--------------------------------

好的,首先可能的解決方案是使用std::vector

+1

(http://liveworkspace.org/code/c31438b6408c37ccb2d458bac3e28859) – chris

+1

這是什麼線應該做的,它甚至如何編譯? 'new unsigned char []'(你大概可以猜到這是怎麼回事。你的問題幾乎肯定是這條線) – jalf

+0

@jalf,顯然MSVC編譯這個混亂。至少VS11有。 – chris

回答

0

編寫一個基於圖像計算數據大小的函數。

然後分配具有該大小的數據

例如,

size_z GetDataSize(const wchar_t* szFilename) 
0

可以很容易地計算出您的GetData函數中所需要的尺寸,所以分配陣列那裏返回它來代替。

你將不得不

unsigned char* GetData(const wchar_t* szFilename, 
         unsigned int& width, 
         unsigned int& height, 
         unsigned int& bpp); 

包含

unsigned char* data = new unsigned char[height * scan_width]; 
// Do the conversion... 
return data; 

main會說

unsigned char* data = GetData(sk_Filename, width, height, bpp); 
1

它無關的delete

問題是Debug Crt Runtime只能在調用內存API時檢查內存完整性,如:malloc,free,realloc,new,delete。

您有一個由Crt檢測到的內存溢出。

顯然,new unsigned char[]不會爲您分配足夠的字節。

移動分配到GetData() proc和調用它:[?那如何編譯]

unsigned char* data = GetData(sk_Filename, width, height, bpp);