Решение
static LinkedList *temp;
в push_back
похоже на ленивый хак. Это не нужно, и ваш код становится еще короче без этого:
template <typename T>
void LinkedList<T>::push_back(T element) {
if (head == nullptr) {
head = get_node(element);
tail = head;
}
else {
LinkedList* node = get_node(element);
tail->next = node;
node->prev = tail;
tail = node;
}
}
Но это только ошибка, которую я нашел для этой указанной c проблемы. Zan Lynx, вероятно, прав, может быть больше ошибок.
Объяснение
Вы получаете неопределенное поведение, потому что обращаетесь к удаленной памяти. Ошибка или ошибка проекта static LinkedList *temp;
в push_back
. Обратите внимание, что temp
всегда будет указывать на последний нажатый элемент. Но в какой-то момент вы удаляете последний элемент! Итак, давайте рассмотрим шаг за шагом:
После lt.push_back(5);
ваш список выглядит следующим образом:
temp (from push_back)
|
56 <-> 2 <-> 3 <-> 4 <-> 5 -> nullptr
| |
head tail
Теперь сотрите delete
s узел со значением 5. Но temp
все еще указывает на память, которая была освобождена 1 , так что вы получите:
temp (from push_back)
|
56 <-> 2 <-> 3 <-> 4 5 [freed]
| |
head tail
После следующей строки lt.push_back(46);
вещи go сумасшедшие. У вас есть следующий код (просто):
void LinkedList<T>::push_back(T element) {
static LinkedList* temp;
if (head == nullptr) {...}
else {
LinkedList* node = get_node(element);
tail->next = node;
tail = node;
tail->prev = temp; // prev->temp is now pointing to freed memory
temp = temp->next; // dereferencing an invalid pointer -> undefined behaviour
}
}
Это приводит к:
temp (from push_back)
5 [deleted] <- |
56 <-> 2 <-> 3 <-> 4 -> 46 -> nullptr ????
| |
head tail
Тогда все идет в ад в корзине с lt.pop_bak();
:
void LinkedList<T>::pop_bak() {
LinkedList* temp;
temp = tail;
tail = tail->prev; // tail->prev is an invalid pointer, now tail is too
tail->next = nullptr; // dereferencing invalid pointer (again)
delete temp;
}
temp (from pop_bak)
|
56 <-> 2 <-> 3 <-> 4 -> 46 [deleted] -> nullptr 5 [deleted] -> nullptr
| |
head tail
Как вы видите, ваш список был полностью урезан, и вы получили два указателя, которые указывают на освобожденную память (например, память, которой вы не владеете, которая содержит данные для мусора). Просто потому, что вы сохранили указатель в static LinkedList *temp;
в push_back
.
1 Хотя в C ++ вы используете
delete
, а не C -функцию
free
Я имею в виду «освобожденную память», потому что, на мой взгляд, она более понятна. Память все еще там, она просто больше не принадлежит вашей программе