【问题标题】:freeing std::list member释放 std::list 成员
【发布时间】:2023-04-02 18:04:02
【问题描述】:

我有一个定义为 std::list<BunnyInfo> bList; 的列表,私有的,在 BunnyInfo 是一个结构的类中

struct BunnyList::BunnyInfo {
    std::string name;
    char gender;
    std::string color;
    unsigned int age : 6; // 0 - 63
    bool mutant;
};

列表通过成员函数增长的地方

void BunnyList::add(int count){
    bListIter iter;
    while(count--){
        BunnyInfo *bNew = &fill(*new BunnyInfo());
        for(iter = bList.begin(); iter != bList.end(); iter++){
            if(iter->age <= bNew->age)
                break;
        }
        bList.insert(iter, *bNew);
    }
}

其中fill() 只是一个为结构生成值的函数。我还有一个成员函数可以删除一半的列表

void BunnyList::reap(){
    int toKill = bList.size() / 2;
    int find;
    bListIter iter;
    while(toKill--){
        find = rng(0, bList.size()-1);
        iter = bList.begin();
        for(int i = 0; i < find; i++)   // traverse list to the find-th node;
            iter++;
        delete &(*iter);
        bList.erase(iter);
    }
}

我的问题是,如何在删除列表成员的同时释放通过add() 分配的资源。我认为delete &amp;(*iter); 会产生错误,因为没有它,程序运行正常。但简单地调用erase() 并不会释放与列表节点关联的BunnyInfo

我是使用 STL 的新手。

【问题讨论】:

  • 你可能想要避免使用std::list,除非你有非常具体的理由使用它。 (std::vector 几乎在所有方面都很出色)
  • 为什么你的 add 函数会分配一个动态的 BunnyInfo,而不是在本地创建一个?
  • 随着列表的增长,列表通过age 排序;我做了很多中间插入,所以我认为向量不太理想。(?)
  • @BenjaminLindley 你是什么意思?
  • @lightburst:事实上,您创建的对象甚至不是被添加到列表中的对象。因为:bList.insert(iter, *bNew);——创建bNew 指向的对象的副本并将该对象存储在列表中。所以实际上,当你调用erase 时,列表会释放对象。但是,您已经泄露了原始对象。

标签: c++ stl dynamic-memory-allocation


【解决方案1】:

由于列表被声明为std::list&lt;BunnyInfo&gt;,它的insert 会复制正在插入的对象,erase 会自动释放该副本。因此,您不需要也不能在该副本上使用delete

由于您的add 分配给new 的对象不是delete(并且不存储在任何数据结构中),因此add 中存在内存泄漏。

如果要在列表中存储指针,则需要将列表声明为std::list&lt;BunnyInfo *&gt;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-11
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 2019-05-20
    相关资源
    最近更新 更多