вызывается исключение нарушения доступа для чтения. _Val и ячейка памяти

по окончании программы информация из односвязного списка должна быть записана в бинарник. при следующем запуске программы из бинарника заполняется список. так вот запись в файл работает, но чтение каждый раз вызывает исключение[1]. пробовал кучу всего, скорее всего допустил очевидную ошибку, но совсем ее не вижу.

само задание:

Данные хранятся в бинарном файле записей, а для обработки считываются в односвязный линейный список (если файл не существует, то создается пустой список). При выходе из программы обработанные данные сохраняются в том же файле. Имя файла с данными задается константой или вводится с клавиатуры. Для взаимодействия с пользователем должно использоваться меню. Обязательные операции для списка: добавление элемента в начало списка, удаление первого элемента списка, просмотр списка, поиск в соответствии с индивидуальным вариантом (две функции). Вывод списка на экран можно выполнять в любом (главное, читабельном) виде.

Поля данных: фамилия пациента, пол, возраст, место проживания (город), диагноз. Определить количество иногородних пациентов, прибывших в клинику. Вывести сведения о пациентах пенсионного возраста.

мой код:

#include <string>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include "Windows.h"

using namespace std;

char tolowerCyr(char c) {
    if (c >= 'А' && c <= 'Я') {
        return c - 'А' + 'а';
    }
    return c;
}

struct patient {
    string lastName;
    char sex;
    int age;
    string city;
    string diagnosis;
};

struct node {
    patient data;
    node* next;
};

class patientList {
    node* head;

public:

    patientList() : head(nullptr) {}
    ~patientList() {
        while (head != nullptr) {
            node* temp = head;
            head = head->next;
            delete temp;
        }
    }

    void push_top(patient& p) {
        node* newNode = new node;
        newNode->data = p;
        newNode->next = head;
        head = newNode;

        cout << "Пациент добавлен в начало списка" << endl;
    }

    void pop_top() {
        if (head == nullptr) {
            cout << "Список пуст" << endl;
            return;
        }

        node* temp = head;
        head = head->next;
        delete temp;

        cout << "Пациент удален из начала списка" << endl;
    }

    void print() {
        node* cur = head;
        int n = 0;

        if (cur == nullptr) {
            cout << "Список пуст" << endl;
            return;
        }

        cout << "-------------------------------------------------------------------------------------------------------" << endl;
        cout << "|  N  |         Фамилия         | Пол | Возраст |          Город          |          Диагноз          |" << endl;
        cout << "-------------------------------------------------------------------------------------------------------" << endl;

        while (cur != nullptr) {
            cout << "| " << setw(3) << left << ++n << " | " << setw(23) << left << cur->data.lastName
                << " |  " << cur->data.sex << "  | " << setw(7) << left << cur->data.age
                << " | " << setw(23) << left << cur->data.city << " | " << setw(25) << left << cur->data.diagnosis << " |" << endl;
            cur = cur->next;
        }

        cout << "-------------------------------------------------------------------------------------------------------" << endl;
    }

    void inputPatient() {
        patient newPatient;
        string tmp;
        bool inpt = true;

        cout << "Введите фамилию: ";
        cin >> newPatient.lastName;

        do {
            cout << "Введите пол: ";
            cin >> tmp;
            transform(tmp.begin(), tmp.end(), tmp.begin(), tolowerCyr);

            if (tmp == "м" || tmp == "муж" || tmp == "мужской") {
                newPatient.sex = 'М';
                inpt = true;
            }
            else if (tmp == "ж" || tmp == "жен" || tmp == "женский") {
                newPatient.sex = 'Ж';
                inpt = true;
            }
            else {
                cout << "Некорректный ввод пола. Мужской - м/муж/мужской. Женский - ж/жен/женский." << endl;
                inpt = false;
            }
        } while (inpt == false);
        
        do {
            cout << "Введите возраст: ";
            cin >> newPatient.age;
            
            if (newPatient.age > 117 || newPatient.age < 1) {
                cout << "Неподходяшее число. Введите число от 1 до 117." << endl;
                inpt = false;
            }
            else { inpt = true; }

        } while (inpt == false);

        cout << "Введите город: ";
        cin >> newPatient.city;
        transform(newPatient.city.begin(), newPatient.city.end(), newPatient.city.begin(), tolowerCyr);

        cout << "Введите диагноз: ";
        cin >> newPatient.diagnosis;
        transform(newPatient.diagnosis.begin(), newPatient.diagnosis.end(), newPatient.diagnosis.begin(), tolowerCyr);

        push_top(newPatient);
    }

    void pension() {
        node* cur = head;
        int n = 0;

        if (cur == nullptr) {
            cout << "Список пуст" << endl;
            return;
        }

        cout << "-------------------------------------------------------------------------------------------------------" << endl;
        cout << "|  N  |         Фамилия         | Пол | Возраст |          Город          |          Диагноз          |" << endl;
        cout << "-------------------------------------------------------------------------------------------------------" << endl;

        while (cur != nullptr) {
            if ((cur->data.sex == 'М' && cur->data.age > 64) || (cur->data.sex == 'Ж' && cur->data.age > 59)) {
                cout << "| " << setw(3) << left << ++n << " | " << setw(23) << left << cur->data.lastName
                    << " |  " << cur->data.sex << "  | " << setw(7) << left << cur->data.age
                    << " | " << setw(23) << left << cur->data.city << " | " << setw(25) << left << cur->data.diagnosis << " |" << endl;
            }
            else { n++; }
            
            cur = cur->next;
        }

        cout << "-------------------------------------------------------------------------------------------------------" << endl;
    }

    void nonresident() {
        node* cur = head;
        int n = 0;
        string tmp = "", SPb = "санкт-петербург";
        bool equal = true;

        if (cur == nullptr) {
            cout << "Список пуст" << endl;
            return;
        }

        while (cur != nullptr) {
            if (cur->data.city != SPb) {
                n++;
                break;
            }

            cur = cur->next;
        }

        cout << "Количество иногородних пациентов: " << n << endl;
    }

    void write() {
        ofstream file("patients", ios::binary | ios::out);
        
        node* cur = head;
        while (cur != nullptr) {
            file.write(reinterpret_cast<const char*>(&cur->data), sizeof(patient));
            cur = cur->next;
        }

        file.close();
    }

    void read() {
        ifstream file("patients", ios::binary | ios::in);

        if (!file.is_open()) {
            ofstream newFile("patients", ios::binary | ios::out);
            if (!newFile.is_open()) {
                cout << "Ошибка при создании файла" << endl;
                return;
            }
            newFile.close();
            cout << "Файл создан" << endl;
            return;
        }

        patient newPatient;
        while (file.read(reinterpret_cast<char*>(&newPatient), sizeof(patient))) {
            push_top(newPatient);
        }

        file.close();
    }
};

int main()
{
    SetConsoleOutputCP(1251);
    SetConsoleCP(1251);

    int menu;

    patientList patients;
    patients.read();

    do {
        cout << "----------------------------------------------------" << endl;
        cout << "|                       МЕНЮ                       |" << endl;
        cout << "----------------------------------------------------" << endl;
        cout << "| 1. Добавить пациента в начало                    |" << endl;
        cout << "| 2. Удалить пациента из начала                    |" << endl;
        cout << "| 3. Вывести список                                |" << endl;
        cout << "| 4. Вывести инофрмацию о пенсионерах              |" << endl;
        cout << "| 5. Определить количество иногородних пациентов   |" << endl;
        cout << "| 0. Выход                                         |" << endl;
        cout << "----------------------------------------------------" << endl;
        cin >> menu;

        switch (menu) {
            case 1:
                system("cls");
                patients.inputPatient();
                break;

            case 2:
                patients.pop_top();
                break;

            case 3:
                system("cls");
                patients.print();
                break;

            case 4:
                system("cls");
                patients.pension();
                break;

            case 5:
                patients.nonresident();
                break;

            case 0:
                patients.write();
                break;
            default:
                cout << "Пункта меню не существует" << endl;
                break;
        }
    } while (menu != 0);

    return 0;
}```


  [1]: https://i.stack.imgur.com/n4zlJ.png

Ответы (0 шт):