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

C+SDL开发遇EXC_BAD_ACCESS错误:SDL_TEXTURE赋值失败求助

问题描述

在macOS Sonoma 14.1系统下使用VSCode+clang编译C项目,尝试通过text_load函数为GAME_TEXTURE指针的texture成员赋值SDL_TEXTURE*时触发EXC_BAD_ACCESS错误。尝试用malloc为fps_texture->texture分配内存后问题依旧。

相关代码

main.c 关键代码

GAME_TEXTURE* fps_texture = NULL;
fps_texture->texture = text_load(app.renderer, fps_font, "TEST"); // 此处报错
if (!fps_texture->texture)
{
   printf("Unable to load font into texture!\n");
}

text_load 函数定义

SDL_Texture* text_load(SDL_Renderer* renderer, TTF_Font* font, char* text)
{
  SDL_Texture* texture = NULL;

  //Render text surface
  SDL_Surface* text_surface = TTF_RenderText_Solid(font, text, TEXT_COLOR);
  if (text_surface == NULL)
  {
    printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError());
  }
  else
  {
    //Create texture from surface pixels
    texture = SDL_CreateTextureFromSurface(renderer, text_surface);
    if (texture == NULL)
    {
      printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
    }
    else
    {
      //Get image dimensions
      // text_texture->width = text_surface->w;
      // text_texture->height = text_surface->h;
    }

    //Get rid of old surface
    SDL_FreeSurface(text_surface);
  }
  
  return texture;
}

GAME_TEXTURE 结构体定义

typedef struct GAME_TEXTURE
{
  SDL_Texture* texture;
  uint32_t width;
  uint32_t height;
} GAME_TEXTURE;

tasks.json 配置

{
  "version": "2.0.0",
  "tasks": [
    {
      "type": "shell",
      "label": "C/C++: clang++ build active file",
      "command": "/usr/bin/clang++",
      "args": [
        "-std=c++17",
        "-stdlib=libc++",
        "-g",
        "main.c",
        "-I",
        "/opt/homebrew/Cellar/sdl2/2.26.5/include/SDL2",
        "-I",
        "/opt/homebrew/Cellar/sdl2_image/2.6.3_1/include/SDL2",
        "-I",
        "/opt/homebrew/Cellar/sdl2_ttf/2.20.2/include/SDL2",
        "-L",
        "/opt/homebrew/Cellar/sdl2/2.26.5/lib",
        "-L",
        "/opt/homebrew/Cellar/sdl2_image/2.6.3_1/lib",
        "-L",
        "/opt/homebrew/Cellar/sdl2_ttf/2.20.2/lib/",
        "-l",
        "SDl2",
        "-l",
        "SDL2_image",
        "-l",
        "SDL2_ttf",
        "-o",
        "main"
      ],
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "problemMatcher": [
        "$gcc"
      ],
      "group": "build",
      "detail": "Task generated by Debugger."
    },
    {
      "type": "cppbuild",
      "label": "C/C++: clang build active file",
      "command": "/usr/bin/clang",
      "args": [
        "-fcolor-diagnostics",
        "-fansi-escape-codes",
        "-g",
        "${file}",
        "-o",
        "${fileDirname}/${fileBasenameNoExtension}"
      ],
      "options": {
        "cwd": "${fileDirname}"
      },
      "problemMatcher": [
        "$gcc"
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      },
      "detail": "Task generated by Debugger."
    }
  ]
}
问题原因及解决方法

核心原因

直接操作了空指针fps_texture。GAME_TEXTURE* fps_texture = NULL;仅声明了指针变量,但未为其分配指向的结构体内存。此时fps_texture指向内存地址0,对fps_texture->texture赋值本质是访问非法内存,必然触发EXC_BAD_ACCESS。

之前尝试用malloc给fps_texture->texture分配内存完全错误——因为fps_texture本身是空指针,连结构体的地址都不存在,根本无法访问它的texture成员。

解决步骤

  1. 为GAME_TEXTURE结构体分配内存
    使用前必须先用malloc申请结构体内存空间:

    GAME_TEXTURE* fps_texture = malloc(sizeof(GAME_TEXTURE));
    // 检查内存分配是否成功
    if (fps_texture == NULL) {
        printf("Failed to allocate memory for GAME_TEXTURE!\n");
        // 添加错误处理逻辑,比如退出程序
        return 1;
    }
    // 初始化结构体成员(可选但推荐,避免脏数据)
    fps_texture->texture = NULL;
    fps_texture->width = 0;
    fps_texture->height = 0;
    
  2. 调用text_load安全赋值
    现在fps_texture已指向合法内存,可安全赋值:

    fps_texture->texture = text_load(app.renderer, fps_font, "TEST");
    if (!fps_texture->texture)
    {
       printf("Unable to load font into texture!\n");
    }
    
  3. 释放内存避免泄漏
    不再使用时,先释放SDL_Texture,再释放结构体:

    if (fps_texture != NULL) {
        if (fps_texture->texture != NULL) {
            SDL_DestroyTexture(fps_texture->texture);
        }
        free(fps_texture);
        fps_texture = NULL; // 避免悬空指针
    }
    

额外注意事项

  • 修正tasks.json中的库拼写:-l SDl2应为-l SDL2,否则编译时可能找不到SDL2库。
  • 确保app.renderer和fps_font是已初始化的合法指针,否则text_load函数也会出错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:58:13