所以我正在使用链接列表列出名称,并且我被赋予了使用该指针和析构函数的任务。我编写的代码是
#include <iostream>
using namespace std;
class node
{
char name[50];
node*next;
public:
friend class sll;
};
class sll:public node
{
public:
node*head;
node*last;
int*k;
friend class node;
sll()
{
head=NULL;
last=NULL;
}
~sll()
{
node*temp2;
node*temp;
temp = head;
while(temp!=NULL)
{
temp2 = temp->next;
delete(temp);
temp = temp2;
}
}
void input()
{
node*temp;
temp = new node;
cout<<"Enter Name"<<endl;
cin>>temp->name;
if(head==NULL)
{
head = temp;
last = temp;
}
else
{
last->next = temp;
last = temp;
}
}
void output()
{
node*temp;
temp = head;
while(temp!=NULL)
{
cout<<temp->name<<" ";
temp = temp->next;
}
}
sll &get()
{
return *this;
}
};
int main()
{
sll obj,obj1;
obj.input();
obj1 = obj.get();
obj1.output();
return 0;
}
我得到的错误是双重释放或损坏
现在,我想得到的是这个特定错误,因为obj1 = obj.get()
复制了obj1中obj的地址。因此,当我尝试删除链接列表时,它给了我错误,因为我要释放两次(因为我有两个sll类的对象)。但是如果是这样,如果我用destructor块替换我为什么没有任何错误
~sll()
{
delete(k);
}
有人可以帮我弄清楚吗?
答案 0 :(得分:0)
问题
该语句将obj复制到obj1:
obj1 = obj.get();
不幸的是,您的班级有赋值运算符。因此,使用默认值,即按成员复制一个成员。不幸的是,所有指针将被完全复制为其相同的值。结果,obj.head
和obj1.head
都指向同一个对象。
当两个链表都在main()
的末尾销毁时,第一个销毁的销毁销毁了所有节点。但这意味着剩余列表中的所有指针都悬空了。当第二个列表被销毁时,这当然会导致尝试删除不再存在的内容!
解决方案
这可以通过实现一个赋值运算符来解决,该赋值运算符通过克隆其节点并指向克隆来构造新列表:
sll& operator=(const sll& o) // assignment operator
{
node *temp; // iterate through original container
temp = o.head;
while(temp!=nullptr)
{ // for every node of the list create a clone
node *clone = new node(*temp);
if(head==nullptr) // add it to the new list
{
head = clone;
last = clone;
}
else
{
last->next = clone;
last = clone;
}
temp = temp->next;
}
return *this;
}
但这还不够,因为在进行复制构造时会发生类似的问题。因此,您还需要一个复制构造函数。
一旦在类中有了指针,就应该考虑应用rule of 3以避免这种情况