Read access violation при удалении объекта структуры

167
10 апреля 2019, 02:50

Имеется такая структура:

struct account {
    string  login;
    string  pass;
    bool    admin;
};

И такая функция:

bool auth() {
    account user;
    account input;
    ifstream fin("users.bin", ios::binary | ios::in);
    if (fin.is_open()) {
        while (true) {
            system("cls");
            cout << "login: ";
            getline(cin, input.login);
            cout << "pass: ";
            getline(cin, input.pass);
            while (!fin.eof()) {
                fin.read((char*)&user, sizeof(user));
                if (input.login == user.login && input.pass == user.pass) {
                    fin.close();
                    system("cls");
                    cout << "hello, " << user.login << "\n" << endl;
                    cout << "press any key...";
                    _getwch();
                    return user.admin;
                }
            }
            system("cls");
            cout << "Incorrect login or password\n" << endl;
            cout << "press any key...";
            _getwch();
            fin.clear();
            fin.seekg(0, ios::beg);
        }
    }
    else {
        cout << "File is not avalible" << endl;
        abort();
    }
}

При завершении работы функции именно у объекта user, видимо, не получается удалиться, и вызывается исключение read access violation

Answer 1
fin.read((char*)&user, sizeof(user));

Вот так - просто в память - можно считывать только то, что называется POD - plain old data. Тот же string - это сложный класс, в котором хранятся указатели на динамически выделенную память и т.п. вещи. Вы считали какой-то указатель, который когда-то - в другой программе, быть может - указывал в какое-то правильное, корректно выделенное место в памяти. А теперь куда он указывает?
Именно. Хрен знает куда.
Потому и получается хрен знает что, когда программа пытается корректно освободить память - непонятно какую, непонятно где.

Категорически нельзя так хранить серьезные вещи. Тот же string, если нужно бинарное хранение, лучше записать как целое число - количество символов, а потом сами символы. А затем, когда считываете, сначала считываете длину, готовите соответствующий буфер, читаете в него строку и собираете объект string.

READ ALSO
Является ли exit(1) крашем программы?

Является ли exit(1) крашем программы?

Можно ли вызов exit(1); назвать падением приложения? При условии вызова exit(1); в любое время выполнения?

194
Неправильно работает код [закрыт]

Неправильно работает код [закрыт]

Вся база не выводится, выводятся только вторые введенные значения

192
Сокращение строки в выводе

Сокращение строки в выводе

Пытаюсь изменить символ в строке на \0, чтобы выводить её не полностью (тк

162