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

C语言SDL2结合Emscripten向HTML5 canvas写文字出现段错误如何解决

问题根因

你的代码存在3个直接触发段错误的核心问题:

  1. 纹理提前销毁:set_font_texture 函数中刚创建完文字纹理就调用 SDL_DestroyTexture 销毁了该资源,后续 mainLoop 访问 ctx->text_texture 时操作的是野指针。
  2. TTF子系统提前终止:get_font_texture 执行完逻辑后直接调用了 TTF_CloseFont 和 TTF_Quit,提前释放了字体资源、终止了TTF相关能力,后续所有文字渲染相关操作都会触发非法访问。
  3. 字体文件未打包进虚拟文件系统:Emscripten默认不会读取本地文件系统的资源,你没有把字体目录打包到WASM的虚拟文件系统中,TTF_OpenFont 会返回空指针,操作空指针直接触发崩溃。

修复步骤

  1. 修改set_font_texture函数,删除提前销毁纹理的代码,新增旧纹理释放逻辑避免内存泄漏:
void set_font_text(struct Context *ctx, const char *text) {
    // 先销毁旧纹理,避免内存泄漏
    if (ctx->text_texture) {
        SDL_DestroyTexture(ctx->text_texture);
        ctx->text_texture = NULL;
    }
    SDL_Color fg = {0,0,0,255};
    SDL_Surface *text_surface = TTF_RenderText_Blended(ctx->font, text, fg);
    // 新增错误判断,避免表面创建失败后续操作崩溃
    if (!text_surface) {
        printf("创建文字表面失败: %s\n", TTF_GetError());
        return;
    }
    ctx->text_texture = SDL_CreateTextureFromSurface(ctx->renderer, text_surface);
    SDL_FreeSurface(text_surface);
    // 移除原来的SDL_DestroyTexture(ctx->text_texture); 这行代码
}
  1. 修改get_font_texture函数,删除提前关闭字体和退出TTF的代码,新增字体加载失败判断:
int get_font_texture(struct Context *ctx) {
    ctx->font = TTF_OpenFont("assets/fonts/Alef-Regular.ttf", 30);
    if (!ctx->font) {
        printf("打开字体失败: %s\n", TTF_GetError());
        return 0;
    }
    set_font_text(ctx, "NEIL DU TOIT");
    // 移除 TTF_CloseFont(ctx->font); 和 TTF_Quit(); 这两行代码
    return 1;
}
  1. 修改编译命令,添加--preload-file参数将assets目录打包到虚拟文件系统:
emcc main.c -s USE_SDL=2 -s WASM=1 -s USE_SDL_TTF=2 -O3 --preload-file assets/ -o main.js

额外说明

emscripten_set_main_loop 执行后不会返回,main函数中主循环之后的资源释放代码永远不会执行,如果需要释放资源可以通过atexit注册退出回调实现。

内容的提问来源于stack exchange,提问作者Neil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:18:01