在下面的代码中,当我添加用箭头指定的行时出现错误:
“./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;
}
答案 0 :(得分:2)
这是因为你在向量中推送元素时会复制元素,但vtx在复制时不会重复,因此在main()的末尾,你将有三个元素指向同一个vtx。当程序终止时,它们中的所有三个都将尝试删除相同的int数组。
答案 1 :(得分:2)
将elm[0]
添加到vec
时,elm[0]
的副本会存储在vec
中。由于您还没有定义复制构造函数,因此编译器使用默认值 - 它通过成员复制执行成员。在这种情况下,它保留指针vtx
的副本。现在你有三个对象指向同一个内存。
当vec
被破坏时,它会在其中两个对象上调用析构函数。他们各自尝试
delete
在同一个指针上。因此错误。
如果您想避免这类错误,请查看Rule of Three。