复制构造函数双向链表中的段错误

时间:2013-08-16 08:57:27

标签: c++ pointers for-loop copy-constructor doubly-linked-list

因此,当我尝试将newPtr的数据设置为等于origPtr的数据时,我在for-control-structure的第一个lopp内收到一个seg错误。我不确定是什么导致它。这可能是误用我的指针吗?还是一个错字?或者也许是我的for循环成语中的范围错误?

List::List(const List &aList): numNodes(aList.numNodes) {
    empty = true;
    forward = true;
    string flag;

    cout << "Copy from head to tail? (y/n): ";
    cin >> flag;
    if(flag=="n")
        forward = false;

    if(!aList.head) {
        head = NULL; //aList is empty. so is this->List.
        tail = NULL;
    } else { // copy 1st Node.
        head = new Node;
        if(forward)
            head->setData(aList.head->getData());
        else // copy in reverse.
            head->setData(aList.tail->getData());
        //copy rest of List.
        Node *newPtr = head; //newPtr points to last Node in new List.

        //origPtr points to nodes in original List.
        if(forward) {
            cout << "Copying normally...\n" << endl;
            for(Node *origPtr=aList.head->getNext(); origPtr!=NULL;
                origPtr=origPtr->getNext()) {
                newPtr = newPtr->getNext();
                newPtr->setData(origPtr->getData()); //SEG FAULT
            } // end for
            cout << "3" << endl;
        } else {
            cout << "Copying in reverse order...\n" << endl;
            for(Node *origPtr=aList.tail->getPrev(); origPtr!=NULL;
                origPtr=origPtr->getPrev()) {
                newPtr = newPtr->getNext();
                newPtr->setData(origPtr->getData()); //SEG FAULT
            } // end for
        } // end if/else
        newPtr->setNext(NULL);
    } // end if/else
    cout << "Done copying!\n" << endl;
} // end copy constructor

如果需要更多代码,我会进行必要的编辑。

另外,我知道c ++ 11的标准是使用nullptr。我不会将它用于此实现。我使用gcc-v4.6.3在Ubuntu 12.04上运行,它不支持c ++ 11。

编辑:谢谢大家!所以我在newPtr指向getNext()之前为我的for循环添加了3行。在我将newPtr定义为指向head之后,我将newNode声明为在下一行指向NULL的Node指针。

            newNode = new Node;
            newNode->setPrev(newPtr);
            newPtr->setNext(newNode);

3 个答案:

答案 0 :(得分:3)

让我们分析以下代码。

  head = new Node;
    if(forward)
        head->setData(aList.head->getData());
    else // copy in reverse.
        head->setData(aList.tail->getData());
    //copy rest of List.
    Node *newPtr = head; //newPtr points to last Node in new List.

在这里,您创建一个Node对象并将其分配给head。然后,您将在头指针中设置列表的最后一个或第一个数据。然后协助newPtr前进。所以到目前为止,newPtr只指向列表中的一个元素。

接下来让我们分析以下代码。

} else {
    cout << "Copying in reverse order...\n" << endl;
    for(Node *origPtr=aList.tail->getPrev(); origPtr!=NULL;
        origPtr=origPtr->getPrev()) {
        newPtr = newPtr->getNext();
        newPtr->setData(origPtr->getData()); //SEG FAULT
    } // end for

你在这里做

newPtr = newPtr->getNext()

现在,因为newPtr只是指向一个元素。执行此操作后,newPtr变为null。现在,当newPtr为null时,以下命令将崩溃

newPtr->setData(origPtr->getData()); //SEG FAULT

在执行newPtr-&gt; getNext()之前,您必须为下一个元素分配内存。

答案 1 :(得分:2)

你这样做

head = new Node;
//...
Node *newPtr = head; //newPtr points to last Node in new List.

然后

newPtr = newPtr->getNext();
newPtr->setData(origPtr->getData()); //SEG FAULT

但是不要在节点上设置下一个指针,除非我们看不到Node代码中的魔法。我怀疑getNext会给你一个NULL Node,导致seg错误。 首先设置数据然后指向下一个节点然后移动到它是更有意义的。

答案 2 :(得分:0)

   for(Node *origPtr=aList.head->getNext(); origPtr!=NULL;
                origPtr=origPtr->getNext()) {
     newPtr = newPtr->getNext();
     newPtr->setData(origPtr->getData()); //SEG FAULT
   } // end for

我看到的问题是您没有为正在创建的新列表分配新内存。您只为头节点创建了新内存。

类似的东西:

for(Node *origPtr=aList.head->getNext(); origPtr!=NULL;
                origPtr=origPtr->getNext()) {
     Node *temp = new Node;
     newPtr->next = temp; // assuming you have next as a member of the class Node.
     newPtr = newPtr->getNext();
     newPtr->setData(origPtr->getData());
   } // end for