1

因此,当我尝试将 newPtr 的数据设置为等于 origPtr 的数据时,我在 for-control-structure 的第一个 lopp 中收到了一个段错误。我不确定是什么原因造成的。这可能是滥用我的指针吗?还是错字?或者我的 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。我不会将它用于此实现。我在 Ubuntu 12.04 上运行 gcc-v4.6.3,它不支持 c++11。

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

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

3 回答 3

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 变为空。现在,在 newPtr 为空的情况下,以下必然会崩溃

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

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

于 2013-08-16T09:23:33.943 回答
2

你来做这件事

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

然后

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

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

于 2013-08-16T09:21:13.073 回答
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
于 2013-08-16T09:29:48.760 回答