使用重载赋值运算符克隆单链表

vin*_*nit 0 c++ linked-list singly-linked-list

我正在尝试用C++实现一个Singly链表类.我已经重载了赋值运算符来克隆列表.克隆本身似乎工作正常,但程序在删除克隆列表时崩溃,这导致我怀疑在复制过程中是否出错.

任何帮助都非常感谢.这是overloaded =运算符的代码:

DLList& DLList::operator=(const DLList& iList)
{
    Node *t = iList.head();
    while(t != NULL)
    {
        push(t->data);
        t = t->next;
    }
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

这是推送操作的代码:

void DLList::push(int data)
{
    Node *n = new Node;
    n->data = data;
    n->next = NULL;
    //n->random = NULL;
    n->next = _head;
    _head = n;
    //cout << "_head" <<_head->data<< "head->next" << (_head->next ? _head->next->data : 0)<<endl;
}
Run Code Online (Sandbox Code Playgroud)

这是主要代码(发生崩溃的地方):

DLList *d = new DLList();
d->push(10);
d->push(20);
d->push(30);
d->push(40);
d->setRandom();
d->display("Original list");  // Displays the original list fine
DLList *d1 = new DLList();
d1 = d;  
d1->display("Cloned list"); //Displays the cloned list fine
delete d;    // works fine
delete d1;  // Crashes here due to segmentation fault, invalid pointer access during delete called as part of destructor)
Run Code Online (Sandbox Code Playgroud)

析构函数代码(如果有帮助):

~DLList()
{
    while(_head != NULL)
    {
        Node *temp = _head;
        _head = _head->next;
        delete temp;  // crashes here during first iteration for the cloned list
    }
}
Run Code Online (Sandbox Code Playgroud)

Jea*_*bre 6

你实际上没有使用赋值运算符!您只是将指针复制到另一个指针.调试代码(或只是添加跟踪)会显示出来

  1. 你没有打电话给你的复制码
  2. 地址dd1是相同的

因此,当您删除第二个列表时,您将删除相同的地址两次.

你真的不需要new这里:

DLList d;
d.push(10);

DLList d1 = d;  // assignment is REALLY called
d1.display("Cloned list");
Run Code Online (Sandbox Code Playgroud)

当您超出变量范围时,将删除对象

如果你想在你的上下文中测试,保持new,改变

d1 = d;
Run Code Online (Sandbox Code Playgroud)

通过

*d1 = *d;  
Run Code Online (Sandbox Code Playgroud)

激活赋值运算符.

另一个建议是:分解你的拷贝代码,使其在赋值运算符和拷贝构造函数之间共享,并且删除代码应该在析构函数和赋值运算符之间共享(以避免在分配两次时发生内存泄漏):未经测试,如果没有测试,请不要激怒我不编译,只是告诉我我会解决它,我已经在这里过度转换:)

DLList& DLList::operator=(const DLList& iList)
{
   destroy(); // or you'll get memory leaks if assignment done twice
   copy(iList);
   return *this;
}
DLList& DLList::DLList(const DLList& iList)
{
   _head = NULL;   // set _head to NULL in all your constructors!!
   copy(iList);       
}
~DLList()
{
     destroy();
}

void DLList::copy(const DLList& iList)  // should be private
{
    Node *t = iList.head();
    while(t != NULL)
    {
        push(t->data);
        t = t->next;
    }
}
void DLList::destroy()  // private
{
    while(_head != NULL)
    {
        Node *temp = _head;
        _head = _head->next;
        delete temp;  // crashes here during first iteration for the cloned list
    }
   _head = NULL;   // calling destroy twice is harmless
  }
Run Code Online (Sandbox Code Playgroud)