2012-09-12 5 views
1

FreeImage로 비트 맵을로드 한 후 내 힙 정리를 도와주세요. 어떻게 든 delete[] data;_ASSERTE(_CrtIsValidHeapPointer(pUserData)) 어설 션을 유발하고이 행을 주석 처리하는 것 이외의 다른 방법을 고칠 수는 없습니다. 메모리 누출이 있습니까? 도움과 설명을 부탁드립니다! 페이스트 빈에서FreeImage delete [] 비트 맵 데이터가 실패합니다.

전체 코드 : http://pastebin.com/dWxz0tjM

비주얼 스튜디오 2012 솔루션 (큰 FreeImage 정적 lib 디렉토리 포함) : 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* data = new unsigned char[height * scan_width]; 
// Do the conversion... 
return data; 

main을 포함

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

는 그것은 delete과 아무 상관이

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

말을 할 것이다.

디버그 Crt 런타임은 malloc, free, realloc, new, delete와 같은 메모리 API 호출 중에 만 메모리 무결성을 검사 할 수 있습니다.

Crt가 감지 한 메모리 초과가 있습니다.

분명히 new unsigned char[]은 충분한 바이트를 할당하지 않습니다.

이 좋아하는 GetData() 시저에 할당을 이동하여 전화

[? 그 컴파일 않는 방법]

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