You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:34:34