Valgrind сообщает мне о некоторых утечках памяти из-за моего метода загрузки текстуры. Я проследил это до одного метода, но это, кажется, утечка в самой библиотеке FreeImage?
(Остальные утечки памяти тоже все из 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;
}
Любая помощь, которую кто-либо может дать, ценится, но не уверен, как отладить эту.
Я вижу проблему с этой строкой:
FIBITMAP *image = FreeImage_ConvertTo32Bits(FreeImage_Load(format, filename.c_str()));
FreeImage_Load()
вызов возвращает FIBITMAP *
что вы должны отпустить, позвонив FreeImage_Unload()
, В вашем коде вы обрабатываете возвращенный указатель как временное значение и передаете его FreeImage_ConvertTo32Bits()
но вы нигде не сохраняете это. Вы теряете память, потому что теряете указатель и больше не можете освободить ресурс.
Обратите внимание, что FreeImage_ConvertTo32Bits()
делает клон растрового изображения, поэтому вы должны позвонить FreeImage_Unload()
выпустить его в дополнение к оригиналу FIBITMAP *
,
Других решений пока нет …