使用Getter获取类私有SDL_Window触发Access Violation错误的解决方法
SDL访问违例错误修复方案
错误原因
你遇到的0xC0000005访问违例,核心问题是提前销毁了SDL窗口对象:
- 创建窗口后,你将指针通过
setWindow存入App类,但紧接着调用SDL_DestroyWindow(window)释放了窗口内存 - 此时
App中保存的window指针变成野指针(指向已被释放的内存区域) - 后续调用
SDL_CreateRenderer时传入这个野指针,SDL内部尝试访问已释放的内存,触发访问违例
修复步骤
- 移除提前销毁窗口的代码:窗口创建并交给
App管理后,不要立即调用SDL_DestroyWindow,窗口销毁逻辑应放在程序结束阶段(比如App类的析构函数中) - 修正错误的SDL错误调用:
SDL_GetError需要加括号调用(SDL_GetError()),代码里的SDL_Error是错误码枚举,要替换为SDL_GetError() - 调整窗口有效性检查时机:窗口创建后立即检查是否成功,不要在销毁之后做无效检查
修改后的代码示例
修正后的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
相关产品推荐
相关产品推荐

