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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:18:47