使用析构函数释放链表



所以我正在使用linklist来制作名称列表,并且我被赋予了一个同时使用此指针和析构函数的任务。我写的代码是

#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 的对象(。但如果是这样,如果我将析构函数块替换为

~sll()
{
delete(k);
}

谁能帮我弄清楚?

问题

该语句将 obj 复制到 obj1 中:

obj1 = obj.get();

不幸的是,您的类具有赋值运算符。 因此使用默认的,它使成员逐个复制。 不幸的是,所有指针都将完全以相同的值进行复制。 因此,obj.headobj1.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; 
}

测试演示

但这还不够,因为在进行复制构造时会出现类似的问题。 所以你还需要一个复制构造函数。

一旦你在类中有指针,你应该考虑应用 3 规则来避免这种情况

最新更新