链接列表的复制构造函数上的隔离错误



我正在编写一个类,该类将用作 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)中。

段错误的原因究竟是什么?为什么此代码在复制构造函数期间失败,但在以其他方式调用时则不失败?

我认为你把它复杂化了,你可以在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;
}

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

相关内容

  • 没有找到相关文章

最新更新