LinkedList的Copy构造函数的Segfault

时间:2014-12-03 22:51:22

标签: c++ linked-list

我正在编写一个类,它将作为Student对象的单链表的容器(自定义类,其规范无关紧要)。除了复制构造函数之外,它功能完备(我可以轻松添加和删除节点)。使用我的复制构造函数,我的目标是只复制列表的数据(即不是指针本身),但由于某种原因它会出现段错误。

以下是相关代码(注释用注释来解释不明确的部分):

LinkedList::LinkedList(const LinkedList& copy) {
    Student s = copy.head->getStudent();
    //Node can be initialized with a Student pointer argument
    head = new Node(new Student(s.getFirstName(), s.getMiddleInitial(),s.getLastName(),s.getSSN(),s.getAge()));
    Node *curr = copy.head->getNext();
    Node* prev = head; //For saving the tail
    while(curr != NULL){
        Student s = curr->getStudent();
        append(s);
        prev = curr;
        curr = curr->getNext();
    }
    tail = prev;
    cout << "Leaving method..." << endl;
}


//Irrelevant methods omitted
void LinkedList::append(Node*& n) {
    cout << "Got to appending to node obj" << endl;
    if (head == NULL) {
        head = tail = n;
     } else {
        tail->setNext(n);
        tail = tail->getNext();
    }
}

void LinkedList::append(Student s) {
    Node* n = new Node(s.getFirstName(),s.getMiddleInitial(),s.getLastName(),s.getSSN(),s.getAge());
    append(n);
}
//From Node.cpp
void Node::setNext(Node*  _next) {
    next = _next; //Next is a Node pointer (i.e. Node*)
}

我想强调一下,添加到原始列表时此代码可以正常工作。只有在复制构造函数中,此代码才会失败。我通过Valgrind运行此代码,我收到以下错误:

==23990== Invalid write of size 8
==23990==    at 0x403018: Node::setNext(Node*) (Node.cpp:86)  //This is the "next = _next" line
==23990==    by 0x402694: LinkedList::append(Node*&) (LinkedList.cpp:81)   
==23990==    by 0x402371: LinkedList::append(Student) (LinkedList.cpp:90)
==23990==    by 0x401F68: LinkedList::LinkedList(LinkedList const&) (LinkedList.cpp:31)

这使我感到困惑,因为指针是(并且应该是)大小为8,被保存到指针(大小为8)。

段错的原因究竟是什么?为什么这个代码在复制构造函数期间失败但在被调用时却没有?

1 个答案:

答案 0 :(得分:1)

我认为你已经过度复杂了,你可以在while循环中完成它:

LinkedList::LinkedList(const LinkedList& copy) {
  Student s = copy.head->getStudent();
//Node can be initialized with a Student pointer argument
  head = new Node(new Student(s.getFirstName(),s.getMiddleInitial(),s.getLastName(),s.getSSN(),s.getAge()));
  Node *curr = copy.head->getNext();
  Node *newListCur = head;
  Node* prev = head; //For saving the tail
  while(curr != NULL){
    Student s = curr->getStudent();
   //important step
    Node* newNode = new Node(new Student(s.getFirstName(),s.getMiddleInitial(),s.getLastName(),s.getSSN(),s.getAge()));
    newListCur->setNext(newNode);
   //
    newListCur = newListCur->getNext();
    curr= curr->getNext();
  }
  cout << "Leaving method..." << endl;
}

这不会检查NULL头,因此您可能需要添加该逻辑