从向量中擦除对象会导致双重释放[重复]

Posted

技术标签:

【中文标题】从向量中擦除对象会导致双重释放[重复]【英文标题】:Erasing object from vector causes double free [duplicate] 【发布时间】:2021-12-10 07:55:07 【问题描述】:

当我使用包含已分配内存的 B 类向量时,发生双重释放错误。

class B


public:
    std::string a;
    std::string b;
    int *hehe;

    B()
    
        a = "Hello";
        b = ", World!";
        hehe = new int[7];
        for (int i = 0; i < 7; ++i) 
            hehe[i] = i;
        
    

    ~B() 
        if (hehe)
            delete[] hehe;
    
;
std::vector<class B> a(5);
    a.erase(a.begin() + 2);

错误信息:

a.out(46830,0x10e0015c0) malloc: *** 对象 0x7ff12dc02a80 错误:未分配指针被释放 a.out(46830,0x10e0015c0) malloc: *** 在 malloc_error_break 中设置断点进行调试

这段代码运行良好。我惊呆了。

std::vector<class B> a(1);
a.erase(a.begin());

【问题讨论】:

我惊呆了 -- 违反了rule of 3。转到重复链接,然后转到标记为 管理资源 的部分,那里的示例看起来很熟悉吗? 在现代 C++ 中,几乎没有必要使用 newnew[](过去 10 年我都没有直接使用过)。使用为您管理资源的容器和智能指针。 【参考方案1】:

您没有定义复制构造函数或移动构造函数。因此,指针hehe 的相同值从一个对象复制到另一个对象,并且析构函数多次释放指针hehe 指向的内存,因为将hehe 的相同值存储在多个对象中对象。

例如复制构造函数可以定义如下

B( const B &b ) : a( b.a ), b( b.b ), hehe( new int[7] )

    for (int i = 0; i < 7; ++i) 
        hehe[i] = b.hehe[i];
    

您还需要明确定义复制赋值运算符。

【讨论】:

以上是关于从向量中擦除对象会导致双重释放[重复]的主要内容,如果未能解决你的问题,请参考以下文章

从向量中擦除指针

在向量中使用擦除时双重释放或损坏(fasttop)。知道它们的索引,你怎么能擦除向量的几个项目?

从向量中删除项目

使用指向值的原始指针从 std::list<Value> 中擦除?

击败从内存中擦除 PE

从类型列表中擦除类型 C++ 元编程