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

C++ std::list存储Object派生类指针删除后无法移除元素报错

问题原因
  • 你在范围for循环遍历std::list的过程中直接调用remove()修改容器结构,会导致当前迭代器及后续迭代器全部失效,触发未定义行为,大部分符合删除条件的元素没有被遍历到,自然无法从列表中移除。
  • 基类Object没有声明虚析构函数,通过基类指针删除派生类Player对象时会出现析构不完全的问题,存在内存泄漏隐患。
  • 你先执行delete obj释放了对象内存,虽然指针本身的地址值没有改变,remove()可以匹配到对应元素,但如果后续逻辑不小心访问该指针指向的内存,就会触发野指针访问崩溃。
修复方案

推荐使用std::list自带的remove_if接口实现删除逻辑,该接口原生支持遍历过程中安全移除元素,是最高效且符合标准的写法,修改步骤如下:

  1. 给基类Object添加虚析构函数,保证派生类对象可以被正确析构:
class Object 
{
public:
    bool needs_delete = false;

    virtual void tick() {}
    virtual void render() {}
    // 新增虚析构函数
    virtual ~Object() = default;
};
  1. 把主函数中原来的删除逻辑范围for循环,替换为remove_if实现:
// 替换原有的删除逻辑for循环
myObjs->remove_if([](Object* obj) {
    if (obj->needs_delete) {
        std::cout << "deleted object\n";
        delete obj;
        return true;
    }
    return false;
});

额外优化建议

你不需要动态创建std::list对象,直接在栈上分配即可,避免不必要的堆内存管理开销:
把std::list<Object*>* myObjs = new std::list<Object*>;修改为std::list<Object*> myObjs;,后续所有myObjs->调用都改为myObjs.即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:06:01