【问题标题】:Double free or corruption when using destructor [duplicate]使用析构函数时双重释放或损坏[重复]
【发布时间】:2014-06-26 18:22:39
【问题描述】:

在下面的代码中,当我添加用箭头指定的行时会出错:

`./a.out' 中的错误:双重释放或损坏(fasttop): 0x00000000007a7030 * 中止(核心转储)

如果我不使用析构函数,代码就可以工作。有什么想法吗?

#include<iostream>
#include<vector>

struct Element
{
    int *vtx;

    ~Element ()
    {
        delete [] vtx;
    }
};

int main ()
{
    Element *elm = new Element [2];
    elm[0].vtx = new int [2]; // <----- adding this gives error

    std::vector <Element> vec;
    vec.push_back (elm[0]);
    vec.push_back (elm[0]);

    return 0;
}

【问题讨论】:

  • @juanchopanza,我不确定 - 这是在问一个问题,“遵循三法则”(或现在,零法则)是一个答案,而不是关于三法则的答案是(因为 OP 在询问之前没有听到这个词)。
  • 如果不进行大修,这段代码就无法正常工作。最简单的解决方案是将vtx 更改为std::vector&lt;int&gt; 并去掉析构函数。即使是复制构造函数也无法按原样帮助您。
  • @Griwes 副本中的信息将回答这个问题。我只是在遵循惯例,但如果这不正确,我很乐意删除近距离投票。
  • @juanchopanza,我只是想知道我选择的被骗者是否比你选择的更正确。

标签: c++ free destructor corruption


【解决方案1】:

这是因为当你将元素推入向量时会复制它,但 vtx 在复制时不会复制,所以在 main() 的结尾,你将有三个元素指向同一个 vtx。当程序终止时,它们三个都会尝试删除同一个 int 数组。

【讨论】:

    【解决方案2】:

    当您将elm[0] 添加到vec 时,elm[0] 的副本将存储在vec 中。由于您尚未定义复制构造函数,因此编译器使用了默认构造函数——它执行一个成员一个成员的复制。在这种情况下,它保留了指针vtx 的副本。现在你有三个对象指向同一个内存。

    vec 被破坏时,它会调用其中两个对象的析构函数。他们每个人都尝试 delete 在同一个指针上。因此出现错误。

    如果您想避免此类错误,请查看Rule of Three

    【讨论】:

    • 基本上问题是这里的浅拷贝。编写一个复制构造函数和赋值运算符,并在您有指针成员时进行深度复制。 ``` Element(const Element& e) { cout
    猜你喜欢
    • 1970-01-01
    • 2019-06-17
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多