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

使用Getter获取类私有SDL_Window触发Access Violation错误的解决方法

SDL访问违例错误修复方案

错误原因

你遇到的0xC0000005访问违例,核心问题是提前销毁了SDL窗口对象:

  • 创建窗口后,你将指针通过setWindow存入App类,但紧接着调用SDL_DestroyWindow(window)释放了窗口内存
  • 此时App中保存的window指针变成野指针(指向已被释放的内存区域)
  • 后续调用SDL_CreateRenderer时传入这个野指针,SDL内部尝试访问已释放的内存,触发访问违例

修复步骤

  1. 移除提前销毁窗口的代码:窗口创建并交给App管理后,不要立即调用SDL_DestroyWindow,窗口销毁逻辑应放在程序结束阶段(比如App类的析构函数中)
  2. 修正错误的SDL错误调用:SDL_GetError需要加括号调用(SDL_GetError()),代码里的SDL_Error是错误码枚举,要替换为SDL_GetError()
  3. 调整窗口有效性检查时机:窗口创建后立即检查是否成功,不要在销毁之后做无效检查

修改后的代码示例

修正后的Init函数

#include "common.h"

void Init() {
    int windowFlag, rendererFlag;
    rendererFlag = SDL_RENDERER_ACCELERATED;
    windowFlag = SDL_WINDOW_SHOWN;

    App application;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cout << "Couldn't initialize SDL! Error:" << SDL_GetError() << std::endl;
        exit(-1);
    }
    else {
        SDL_Window* window = SDL_CreateWindow("Shoot em' up", 
            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 
            SCREEN_WIDTH, SCREEN_HEIGHT, windowFlag);
        
        // 创建后立即检查窗口是否成功
        if (!window) {
            std::cout << "Window not initialized! Error:" << SDL_GetError() << std::endl;
            exit(-1);
        }
        application.setWindow(window);

        SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
        
        SDL_Renderer* renderer = SDL_CreateRenderer(application.getWindow(), -1, rendererFlag);
        application.setRenderer(renderer);
        
        if (!renderer) {
            std::cout << "Renderer not initialized! Error:" << SDL_GetError() << std::endl;
            // 渲染器创建失败时,先销毁已创建的窗口
            SDL_DestroyWindow(window);
            exit(-1);
        }
    }
}

建议补充App类的析构函数(防止内存泄漏)

在App类头文件中声明析构函数,实现文件中添加:

App::~App() {
    if (renderer) {
        SDL_DestroyRenderer(renderer);
        renderer = nullptr;
    }
    if (window) {
        SDL_DestroyWindow(window);
        window = nullptr;
    }
}

额外注意事项

  • SDL资源(窗口、渲染器)遵循创建者负责销毁的原则,最好将资源生命周期与App类绑定,通过构造/析构函数统一管理
  • 输出错误信息时,必须确保SDL_GetError()被正确调用(加括号),否则输出的是函数指针而非实际错误内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:42:07