Я пишу класс, который будет служить контейнером для односвязного списка для объектов Student (пользовательский класс, спецификация которого не имеет значения). Он отлично работает (я могу легко добавлять и удалять узлы), за исключением конструктора копирования. С моим конструктором копирования я стараюсь скопировать только данные списка (т. Е. Не сами указатели), но по какой-то причине он segfaults.Segfault on Copy Constructor LinkedList
Ниже приведен соответствующий код (Аннотированный с комментариями объяснить неоднозначные части):
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).
Что именно является причиной segfault? Почему этот код выходит из строя во время конструктора копирования, но не при вызове иначе?
Это не размер недопустимой записи, а скорее запись (размером 8), которая недействительна. Похоже, что 'tail' может быть недействительным (это объект, который вы передаете' append') - вы уверены, что он правильно инициализирован? – Cameron
Вам не хватает значительного кода. Взгляните на [MCVE] (https://stackoverflow.com/help/mcve). – Deduplicator
@Cameron Можете ли вы объяснить, что может привести к тому, что запись будет недействительной? Даже если только в общем случае. – ahjohnston25