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

C++项目中forward_list与Vector结合,Vector数据作用域结束后丢失求助

问题根源与解决方案

你的问题核心是Frame对象拷贝时的浅拷贝导致悬空指针,进而在局部变量销毁后出现垃圾数据。咱们一步步拆解问题并给出解决办法:

为什么会出现垃圾数据?

你在InsertFrame()里创建了局部的Frame t_frame,然后把它插入到forward_list<Frame>中。此时如果Frame的拷贝构造函数是浅拷贝(要么是编译器生成的默认拷贝,要么你声明了但没正确实现深拷贝),就会触发以下连锁问题:

  1. 新插入到forward_list的Frame对象,它的displays vector和t_frame的displays指向完全相同的堆上Display对象。
  2. 当InsertFrame()函数结束时,局部变量t_frame被销毁,它的析构函数会delete所有displays里的Display指针。
  3. 这就导致forward_list里的Frame的displays中的指针变成了悬空指针,访问时自然就是垃圾数据。

解决步骤

1. 给Display类添加虚克隆方法

因为Display是多态基类,我们需要一个虚方法来让子类创建自身的拷贝,这样Frame拷贝时才能正确复制不同类型的Display对象:
在Display.h中添加:

// 虚克隆方法,子类必须实现
virtual Display* clone() const = 0;

2. 在子类中实现clone方法

SystemMemoryDisplay.h

SystemMemoryDisplay* clone() const override {
    return new SystemMemoryDisplay(*this);
}

GPUMemoryDisplay.h

GPUMemoryDisplay* clone() const override {
    return new GPUMemoryDisplay(*this);
}

3. 实现Frame的深拷贝构造函数

在Frame.cpp中补充拷贝构造函数的定义,对每个Display进行深拷贝:

Frame::Frame(const Frame& other) {
    fileName = other.fileName;
    // 遍历原Frame的所有Display,克隆每个对象
    for (Display* display : other.displays) {
        displays.push_back(display->clone());
    }
}

4. (可选但推荐)实现Frame的赋值运算符重载

为了避免后续使用赋值操作时再次出现浅拷贝问题,补充赋值运算符的深拷贝实现:
首先在Frame.h中声明:

Frame& operator=(const Frame& other);

然后在Frame.cpp中实现:

Frame& Frame::operator=(const Frame& other) {
    if (this == &other) return *this; // 防止自赋值
    
    // 先清理当前对象的资源
    for (Display* display : displays) {
        delete display;
    }
    displays.clear();
    
    // 深拷贝数据
    fileName = other.fileName;
    for (Display* display : other.displays) {
        displays.push_back(display->clone());
    }
    
    return *this;
}

额外的优化建议

  • 尽量用std::string代替char*来存储name,这样可以避免手动管理内存,减少内存泄漏或重复释放的风险。比如把Display类里的char* name改成std::string name,这样构造函数和拷贝构造函数都能简化很多。
  • 在InsertFrame()中,你创建p_name的代码可以直接去掉,直接把d_name传给Display的构造函数(如果改成string的话)。

内容的提问来源于stack exchange,提问作者G. McLeod

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:43:12