在实现双向链表的复制构造函数时遇到问题

Having trouble implementing a copy constructor for a doubly linked list

提问人:bpsNomad 提问时间:9/25/2019 最后编辑:bpsNomad 更新时间:9/25/2019 访问量:497

问:

我正在努力为双链表实现复制构造函数。程序编译,但我在使用复制构造函数中的“push_back”函数将新创建的节点添加到列表中时遇到了问题。下面是有问题的复制构造函数和push_back函数。

List::List(const List& rhs) // Copy constructor
{
    //this pointer is for the list that is being copied from
    Node* rhsNodePtr;

    //setting the new pointer to the first node of the old list
    rhsNodePtr = rhs.first;

    //looping until the end of the list
    while(rhsNodePtr != nullptr){

        //declaring new node to copy data into
        Node* newNode = new Node("");

        //copying node data from original list into new node
        newNode->data = rhsNodePtr->data;

        //adding new copied node to a new list
        push_back(newNode->data);

        //advancing the old list pointer location for the loop
        rhsNodePtr = rhsNodePtr->next;
    }
}

void List::push_back(string element)
{ 
   Node* new_node = new Node(element);
   if (last == nullptr) // List is empty
   {  
      first = new_node;
      last = new_node;
   }
   else
   {  
      new_node->previous = last;
      last->next = new_node;
      last = new_node;
   }
}

如果我遗漏了任何相关细节,我深表歉意。请注意,我不只是在寻找解决方案或更正,而是在寻找为什么 push_back();函数在我当前的实现中不起作用。

编辑:调用 push_back 函数后,复制构造函数中的 while 循环卡住。

编辑:“First”和“last”在 List 类声明中初始化,并在构造函数中都设置为“nullptr”。

编辑:在运行调试器后,我了解到该行的push_back函数中发生了非法的内存访问(分段错误)last->next = new_node;

C++ 链表 复制构造函数

评论


答:

3赞 NotFound 9/25/2019 #1

您没有在复制构造函数中进行初始化。因此,push_back被调用时带有垃圾。last

顺便说一句,我认为没有必要,你也没有释放它。你可以直接。newNodepush_back(rhsNodePtr->data);

2赞 Remy Lebeau 9/25/2019 #2

你的复制构造函数没有初始化 and(除非你在类声明中这样做,你没有显示),它还会在每次循环迭代时泄漏一个。firstlastNode

请尝试以下操作:

List::List(const List& rhs)
    : first(nullptr), last(nullptr) // <-- add this if needed
{
    Node* rhsNodePtr = rhs.first;
    while (rhsNodePtr) {
        push_back(rhsNodePtr->data); // <-- no need to allocate a new Node for this call
        rhsNodePtr = rhsNodePtr->next;
    }
}

void List::push_back(string element)
{ 
   Node* new_node = new Node(element);
   new_node->previous = last;
   new_node->next = nullptr; // <-- add this if needed
   if (!first) first = new_node;
   if (last) last->next = new_node;
   last = new_node;
}

评论

0赞 bpsNomad 9/25/2019
更新了我的代码以反映您所做的更改。通过调试器运行它后,行中似乎存在非法的内存访问,这也发生在我的原始push_back实现中。if(last) last->next = new_node;
1赞 Remy Lebeau 9/25/2019
这意味着您的其他方法未正确管理,导致它指向无效的 .或者,如果要调用无效对象。使用调试器进行验证。ListlastNodepush_back()List
0赞 bpsNomad 9/25/2019
阅读您的建议后,我注释掉了我的“擦除”功能,程序运行没有问题,因此该功能一定存在问题。谢谢。
0赞 Remy Lebeau 9/25/2019
您可能忘记更新,或者错误地更新,从 .lastNodeList