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

Having trouble implementing a copy constructor for a doubly linked list

我正在努力为双向链表实现复制构造函数。该程序可以编译,但我 运行 使用复制构造函数中的 "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(); 原因的解释。函数在我当前的实现中不起作用。

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

编辑:"First" 和 "last" 在列表 class 声明中初始化,并在构造函数中都设置为 "nullptr"。

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

您没有在复制构造函数中初始化 last。所以 push_back 被调用时带有垃圾。

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

你的复制构造函数没有初始化 firstlast(除非你在 class 声明中这样做,你没有显示),它也泄漏了 Node 在每个循环迭代中。

试试这个:

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