使用SDL_ttf打印游戏生命值出现内存泄漏,求排查方案
SDL_ttf渲染生命值文本时内存泄漏导致游戏崩溃的解决办法
问题描述
我在使用SDL_ttf为游戏在屏幕上打印生命值信息时遇到了内存泄漏问题:游戏启动后能正常运行一段时间(显示文本等内容),但数秒后就停止响应。我已经确认在调用SDL_RenderCopy后释放了textSurface,其余代码也测试过没问题,100%确定是renderHealth函数导致的泄漏。
相关代码如下:
SDLText.h
class SDLText { SDL_Surface* textSurface; SDL_Texture* text; TTF_Font * font; ... }
SDLText.cpp
void SDLText::renderHealth( int health) { font = TTF_OpenFont("fonts/OpenSans-Regular.ttf", 80); if (font == NULL) { printf("font error"); } std::string score_text = "health: " + std::to_string(health); SDL_Color textColor = {255, 255, 255, 0}; textSurface = TTF_RenderText_Solid(font, score_text.c_str(), textColor); text = SDL_CreateTextureFromSurface(gRenderer, textSurface); SDL_Rect Message_rect; //create a rect Message_rect.x = 120; //controls the rect's x coordinate Message_rect.y = 5; // controls the rect's y coordinte Message_rect.w = 100; // controls the width of the rect Message_rect.h = 20; // controls the height of the rect SDL_RenderCopy(gRenderer, text, NULL, &Message_rect); SDL_FreeSurface(textSurface); SDL_DestroyTexture(text); }
问题分析
你忽略了一个关键细节:每次调用renderHealth时都会通过TTF_OpenFont打开字体文件,但没有在函数结束时关闭这个字体资源。
TTF_OpenFont会为字体分配内存空间,每调用一次就会占用新的内存,而如果不调用TTF_CloseFont释放,这些内存会一直被占用。随着游戏运行中不断调用renderHealth(比如每帧都更新生命值显示),内存会被快速耗尽,最终导致游戏停止响应。
你已经正确释放了textSurface和text纹理,但漏掉了字体资源的释放——这正是内存泄漏的根源。
解决方案
只需要在函数末尾添加TTF_CloseFont(font);,确保每次打开字体后都及时释放对应的资源:
修改后的renderHealth函数:
void SDLText::renderHealth( int health) { font = TTF_OpenFont("fonts/OpenSans-Regular.ttf", 80); if (font == NULL) { printf("font error"); return; // 建议添加return,避免后续使用空指针引发错误 } std::string score_text = "health: " + std::to_string(health); SDL_Color textColor = {255, 255, 255, 0}; textSurface = TTF_RenderText_Solid(font, score_text.c_str(), textColor); text = SDL_CreateTextureFromSurface(gRenderer, textSurface); SDL_Rect Message_rect; //create a rect Message_rect.x = 120; //controls the rect's x coordinate Message_rect.y = 5; // controls the rect's y coordinte Message_rect.w = 100; // controls the width of the rect Message_rect.h = 20; // controls the height of the rect SDL_RenderCopy(gRenderer, text, NULL, &Message_rect); SDL_FreeSurface(textSurface); SDL_DestroyTexture(text); TTF_CloseFont(font); // 新增:释放字体资源 }
额外提个优化建议:其实不需要每次渲染都打开字体文件,你可以在SDLText类的构造函数中打开一次字体,在析构函数中关闭,这样能减少文件IO和内存操作的开销,游戏性能会更好哦。
内容的提问来源于stack exchange,提问作者Albin Gjoka
相关产品推荐
相关产品推荐

