2014-02-12 5 views
0

Valgrind дает мне отчет о некоторых утечках памяти из метода текстурной загрузки, который у меня есть. Я проследил его до одного метода, но, похоже, это утечка в самой библиотеке FreeImage?FreeImage_Load Memory Leak

(Остальные утечки памяти все из FreeImage_Load тоже здесь опущено)

==4295== 4,320,746 (8 direct, 4,320,738 indirect) bytes in 1 blocks are definitely lost in loss record 210 of 210 
==4295== at 0x4C2CD7B: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==4295== by 0x85148C: FreeImage_AllocateHeaderT (in /tmp/lab) 
==4295== by 0x851913: FreeImage_AllocateHeader (in /tmp/lab) 
==4295== by 0x8698AE: Load(FreeImageIO*, void*, int, int, void*) (in /tmp/lab) 
==4295== by 0x855B44: FreeImage_LoadFromHandle (in /tmp/lab) 
==4295== by 0x855BE0: FreeImage_Load (in /tmp/lab) 
==4295== by 0x41433F: Texture::LoadTexture(std::string, float, float) (Texture.cpp:7) 
==4295== by 0x417E2B: World::LoadTextures() (World.cpp:27) 
==4295== by 0x4119E5: main (project_main.cpp:217) 
==4295== 
==4295== LEAK SUMMARY: 
==4295== definitely lost: 12,328 bytes in 17 blocks 
==4295== indirectly lost: 15,095,237 bytes in 554 blocks 
==4295==  possibly lost: 845,677 bytes in 93 blocks 
==4295== still reachable: 47,631 bytes in 425 blocks 
==4295==   suppressed: 0 bytes in 0 blocks 

Это показывает, что утечка находится в методе Texture :: LoadTexture, вот этот метод:

GLuint Texture::LoadTexture(std::string filename, float width, float height){ 

    //Load Image 
    FREE_IMAGE_FORMAT format = FreeImage_GetFileType(filename.c_str(), 0);  
    FIBITMAP *image = FreeImage_ConvertTo32Bits(FreeImage_Load(format, filename.c_str())); 
    BYTE *bits = FreeImage_GetBits(image); 

    //Get width, height, bitnumber 
    int w = FreeImage_GetWidth(image); 
    int h = FreeImage_GetHeight(image); 
    int nBPP = FreeImage_GetBPP(image); 

    std::cout<<filename<<" "<<w<<"*"<<h<< " " << nBPP << std::endl; 

    //Generate texture references 
    GLuint textureID; 
    glGenTextures(1, &textureID); 
    //Bind 
    glBindTexture(GL_TEXTURE_2D, textureID); 
    //Set parameters 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);  
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 

    //Generate actual texture from image data (mipmaps) 
    gluBuild2DMipmaps(GL_TEXTURE_2D, 3, w, h, GL_BGRA, GL_UNSIGNED_BYTE, bits); 

    //Unload image 
    FreeImage_Unload(image);    

    //Add texture info to a map 
    textures.insert(std::pair<GLuint, TextureInfo>(textureID, TextureInfo(textureID, w, h, nBPP)));  

    if (glGetError()) { 
     std::cout << "There was an error loading the texture" << std::endl; 
    } 

    //Return OpenGL textureID 
    return textureID; 
} 

Любая помощь, которую кто-либо может дать, оценил, не уверен, как идти об отладке этого.

ответ

0

Я вижу проблему с этой линией:

FIBITMAP *image = FreeImage_ConvertTo32Bits(FreeImage_Load(format, filename.c_str())); 

FreeImage_Load() вызов возвращает FIBITMAP *, что вы должны освободить по телефону FreeImage_Unload(). В коде вы обрабатываете возвращаемый указатель как временное значение и передаете его FreeImage_ConvertTo32Bits(), но вы нигде не сохраняете его. Вы теряете память, потому что теряете указатель и больше не можете освобождать ресурс.

Обратите внимание, что FreeImage_ConvertTo32Bits()делает клон растрового изображения, так что вы должны вызвать FreeImage_Unload() выпустить его в дополнение к первоначальному FIBITMAP *.

+0

Это исправлено, спасибо! – rilott