ALLEGRO_DISPLAY赋值触发std::runtime_error异常排查求助
问题分析与解决方案
让我们一步步拆解你遇到的问题:
1. 核心逻辑错误:addDisplay的判断条件完全写反了
这是你触发异常的直接原因!看你的addDisplay实现:
void DisplayManager::addDisplay(ALLEGRO_DISPLAY &display) { if(!mDisplay) { throw std::runtime_error("Failed to create display: A display is already created."); } mDisplay = &display; }
这里的!mDisplay表示当mDisplay是空指针(也就是还没有任何显示被添加)时抛出异常,但你的需求明明是“不允许创建多个显示”——正确逻辑应该是:当mDisplay已经不为空(已经存在一个显示)时,才抛出异常阻止添加。
第一次调用addDisplay时,mDisplay初始是nullptr,直接触发了异常,这就是你看到的报错根源。
2. 为什么换成std::vector后异常消失?
因为你换成vector后,只是调用push_back存储指针,没有加任何判断逻辑——自然不会触发抛异常的代码,所以看起来“正常”了,但这只是避开了错误,不是解决了原问题的逻辑漏洞。
3. 关于异常无法捕获的问题
你说添加try-catch无法捕获异常,大概率是两个原因:
- 捕获的异常类型不匹配:确保你的
catch语句是针对std::runtime_error的,比如写成catch(const std::runtime_error& e),而不是其他错误的类型。 - IDE的异常中断设置:比如在Visual Studio中,默认会在C异常抛出时自动中断调试,即使你写了
catch。你可以通过「调试→窗口→异常设置」,取消勾选C异常的“抛出”选项,这样调试时会让catch块正常处理异常。
另外,你的createDisplay里有个多余的判断:
if(!manager) { throw std::runtime_error("No display manager."); }
getInstance返回的是静态局部变量的地址,永远不可能是空指针,这个判断可以直接删掉。
修正后的代码
把addDisplay的判断逻辑反过来就解决了核心问题:
void DisplayManager::addDisplay(ALLEGRO_DISPLAY &display) { if(mDisplay != nullptr) { // 已有显示时才抛出异常 throw std::runtime_error("Failed to create display: A display is already created."); } mDisplay = &display; }
额外建议:管理显示的生命周期
你的DisplayManager持有了ALLEGRO_DISPLAY的指针,但目前没有处理它的销毁。建议在DisplayManager的析构函数中调用al_destroy_display(mDisplay);,或者明确约定谁负责销毁显示对象,避免出现野指针或内存泄漏。
内容的提问来源于stack exchange,提问作者kovac
相关产品推荐
相关产品推荐

