使用Destructor取消分配链接列表

时间:2018-08-23 19:51:47

标签: c++

所以我正在使用链接列表列出名称,并且我被赋予了使用该指针和析构函数的任务。我编写的代码是

#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);
}

有人可以帮我弄清楚吗?

1 个答案:

答案 0 :(得分:0)

问题

该语句将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; 
}

Test demo

但这还不够,因为在进行复制构造时会发生类似的问题。因此,您还需要一个复制构造函数。

一旦在类中有了指针,就应该考虑应用rule of 3以避免这种情况