C++ 使用析构函数时双重释放或损坏

C++ 使用析构函数时双重释放或损坏,c++,free,destructor,corruption,C++,Free,Destructor,Corruption,在以下代码中,当我添加时,用箭头指定的行给出错误: “./a.out”中出错:双重释放或损坏(fasttop): 0x00000000007A7300*中止(堆芯转储) 如果我不使用析构函数,代码就会工作。有什么想法吗 #include<iostream> #include<vector> struct Element { int *vtx; ~Element () { delete [] vtx; } }; int

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

“./a.out”中出错:双重释放或损坏(fasttop): 0x00000000007A7300*中止(堆芯转储)

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

#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;
}
#包括
#包括
结构元素
{
int*vtx;
~Element()
{
删除[]vtx;
}
};
int main()
{
元素*elm=新元素[2];

elm[0].vtx=new int[2];//这是因为在向量中推送元素时会复制元素,但在复制时不会复制vtx,因此在main()的末尾,将有三个元素指向相同的vtx。当程序终止时,三个元素都会尝试删除相同的int数组。

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

vec
被析构函数时,它调用其中两个对象上的析构函数。它们各自尝试
删除同一指针上的
。因此出现错误


如果你想避免这样的错误,请按此顺序查看。

1)2)3)@juanchopanza,我不确定-这是问一个问题,其中“遵循三法则”(或者现在是零法则)是一个答案,而不是关于三法则是什么的答案(因为OP在提问之前没有听到这个词)。如果不进行彻底检查,这段代码就无法正常工作。最简单的解决方案是将
vtx
更改为
std::vector
,并去掉析构函数。即使是复制构造函数也无法帮到您。@Griwes副本中的信息可以回答这个问题。我只是按照常规做法,但如果不是这样的话“不对,我很高兴取消接近票。@juanchopanza,我只是想知道我选择作为dupe的那一个是否比你选择的那一个更合适。基本上问题是这里的浅复制。编写一个复制构造函数和赋值运算符,并在有指针成员时进行深度复制。``元素(const-Element&e){cout