Программа завершается со значением 3221225477 C++
В структуре содержится информация о названии книги, авторе книги и года издания. Нужно удалить книги по заданному автору, используя класс List. Методом в данном случае будет Del. Допустим, список состоит из таких элементов:
(Book C / Author C / 2010, Book D / Author D / 2015, Book A / Author A / 2000, Book B / Author B / 2005)
Как только программа начинает запрашивать ввод для удаления книги (элемента списка) по заданному автору, то она завершается со значением 3221225477. Что может быть не так в этой программе?
Обновлено. Код сократил на несколько десятков строк. Если где-то можно ещё сократить, то вопрос будет отредактирован.
Ожидаемый результат после удаления элемента списка по автору, например, Author A:
(Book C / Author C / 2010, Book D / Author D / 2015, Book B / Author B / 2005)
Конечный результат:
List L:
(Book C / Author C / 2010, Book A / Author A / 2000, Book B / Author B / 2005)
Вставляем новый элемент списка L на 2-ю позицию (индекс 1)
Input position: 2
Input new data:
Bookname - Book D
Author - Author D
Year - 2015
List L до удаления третьего элемента (индекс 2):
(Book C / Author C / 2010, Book D / Author D / 2015, Book A / Author A / 2000, Book B / Author B / 2005)
Input author:
--------------------------------
Process exited after 17.94 seconds with return value 3221225477
Для продолжения нажмите любую клавишу . . .
Код программы:
struct Book {
string book_name; // название книги
string author; // автор книги
int year; // год издания
Book * next, * prev;
};
class List {
// Голова, хвост
Book * Head, * Tail;
// Количество элементов
int Count;
public:
// Конструктор
List();
// Конструктор копирования
List(const List&);
// Деструктор
~List();
// далее определены методы, но я их не указал, чтобы сократить
// код до минимального воспроизводимого примера, если это возможно
};
// Конструктор
List::List() {
// Изначально список пуст
Head = Tail = NULL;
Count = 0;
}
// Конструктор копирования
List::List(const List & L) {
Head = Tail = NULL;
Count = 0;
// Голова списка, из которого копируем
Book * temp = L.Head;
// Пока не конец списка
while (temp != 0) {
// Передираем данные
AddTail(*temp);
temp = temp->next;
}
}
// Деструктор
List::~List() {
// Удаляем все элементы
DelAll();
}
// Удаление элемента, если параметр не указывается,
// то функция его запрашивает
void List::Del() {
string del_author;
cout << "Input author: ";
getline(cin, del_author);
// Счетчик
int i = 1;
Book * Del = Head;
while (true) {
// Доходим до элемента, который удаляется
Del = Del->next;
i++;
if (del_author == Del->author)
break;
}
// Доходим до элемента,
// который предшествует удаляемому
Book * PrevDel = Del->prev;
// Доходим до элемента, который следует за удаляемым
Book * AfterDel = Del->next;
// Если удаляем не голову
if (PrevDel != 0 && Count != 1)
PrevDel->next = AfterDel;
// Если удаляем не хвост
if (AfterDel != 0 && Count != 1)
AfterDel->prev = PrevDel;
// Удаляются крайние?
if (i == 1)
Head = AfterDel;
if (i == Count)
Tail = PrevDel;
// Удаление элемента
if (del_author == Del->author)
delete Del;
else
cout << "No such author!\n\n";
Count--;
}
// Вставка элемента, если параметр не указывается,
// то функция его запрашивает
void List::Insert(int pos) {
// если параметр отсутствует или равен 0, то запрашиваем его
if (pos == 0) {
cout << "Input position: ";
cin >> pos;
cin.ignore();
cout << "\n";
}
// Позиция от 1 до Count?
if (pos < 1 || pos > Count + 1) {
// Неверная позиция
cout << "Incorrect position !!!\n";
return;
}
// Если вставка в конец списка
if (pos == Count + 1) {
// Вставляемые данные
Book new_element;
cout << "Input new data:\n";
cout << "Bookname - ";
getline(cin, new_element.book_name);
cout << "Author - ";
getline(cin, new_element.author);
cout << "Year";
cin >> new_element.year;
// Добавление в конец списка
AddTail(new_element);
return;
}
else if (pos == 1) {
// Вставляемые данные
Book new_element;
cout << "Input new data:\n";
cout << "Bookname - ";
getline(cin, new_element.book_name);
cout << "Author - ";
getline(cin, new_element.author);
cout << "Year - ";
cin >> new_element.year;
cout << "\n";
// Добавление в начало списка
AddHead(new_element);
return;
}
// Счетчик
int i = 1;
// Отсчитываем от головы n - 1 элементов
Book * Ins = Head;
while (i < pos) {
// Доходим до элемента,
// перед которым вставляемся
Ins = Ins->next;
i++;
}
// Доходим до элемента,
// который предшествует
Book * PrevIns = Ins->prev;
// Создаем новый элемент
Book * temp = new Book;
// Вводим данные
cout << "Input new data:\n";
cout << "Bookname - ";
getline(cin, temp->book_name);
cout << "Author - ";
getline(cin, temp->author);
cout << "Year - ";
cin >> temp->year;
cout << "\n";
// настройка связей
if (PrevIns != 0 && Count != 1)
PrevIns->next = temp;
temp->next = Ins;
temp->prev = PrevIns;
Ins->prev = temp;
Count++;
}
// Добавление в начало списка
void List::AddHead(Book &bk) {
// новый элемент
Book * temp = new Book;
// Предыдущего нет
temp->prev = 0;
// Заполняем данные
temp->book_name = bk.book_name;
temp->author = bk.author;
temp->year = bk.year;
// Следующий - бывшая голова
temp->next = Head;
// Если элементы есть?
if (Head != 0)
Head->prev = temp;
// Если элемент первый, то он одновременно и голова и хвост
if (Count == 0)
Head = Tail = temp;
else
// иначе новый элемент - головной
Head = temp;
Count++;
}
// Добавление в конец списка
void List::AddTail(Book &bk) {
// Создаем новый элемент
Book * temp = new Book;
// Следующего нет
temp->next = 0;
// Заполняем данные
temp->book_name = bk.book_name;
temp->author = bk.author;
temp->year = bk.year;
// Предыдущий - бывший хвост
temp->prev = Tail;
// Если элементы есть?
if (Tail != 0)
Tail->next = temp;
// Если элемент первый, то он одновременно и голова и хвост
if (Count == 0) {
Head = Tail = temp;
}
else {
// иначе новый элемент - хвостовой
Tail = temp;
}
Count++;
}
// Печать списка
void List::Print() {
// Если в списке присутствуют элементы, то пробегаем по нему
// и печатаем элементы, начиная с головного
if (Count != 0) {
Book * temp = Head;
cout << "(";
while (temp->next != 0) {
cout << temp->book_name << " / ";
cout << temp->author << " / ";
cout << temp->year << ", ";
temp = temp->next;
}
cout << temp->book_name << " / ";
cout << temp->author << " / ";
cout << temp->year << ")";
}
cout << "\n\n";
}
// Тестовый пример
int main() {
setlocale(LC_CTYPE, "rus");
List L;
const int n = 3;
Book data[n];
data[0].book_name = "Book A";
data[0].author = "Author A";
data[0].year = 2000;
data[1].book_name = "Book B";
data[1].author = "Author B";
data[1].year = 2005;
data[2].book_name = "Book C";
data[2].author = "Author C";
data[2].year = 2010;
// Добавляем элементы, стоящие на четных индексах, в голову
// на нечетных - в хвост
for (int i = 0; i < n; i++)
if (i % 2 == 0)
L.AddHead(data[i]);
else
L.AddTail(data[i]);
// Распечатка списка
cout << "List L:\n";
L.Print();
// Вставка элемента в список
cout << "Вставляем новый элемент списка L на 2-ю позицию (индекс 1)\n";
L.Insert();
// Удаляем из списка Book A / Author A / 2000 на третьей позиции
cout << "List L до удаления третьего элемента (индекс 2):\n";
L.Print();
L.Del();
cout << "List L после выполнения команды L.Del():\n";
L.Print();
}
Ответы (1 шт):
Вот в этом цикле
while (true) {
// Доходим до элемента, который удаляется
Del = Del->next;
i++;
if (del_author == Del->author)
break;
}
очень было бы неплохо проверять, а существует ли Del->Next.
Программа падает из-за того, что вы пытаетесь разыменовывать nullptr.
И у вас первый элемент списка не участвует в сравнении - вы сразу делаете Del = Head->Next; по сути, а потом только проверяете значение if (del_author == Del->author)