Stefan_Lang
Как сказал Йохен Арндт, вы неправильно сохраняете строку, и в результате она также неправильно читается. Что еще более важно, в конце программы деструктор этого string
вызывается, предполагая правильную инициализацию string
- и в этот момент он падает.
Ваша проблема начинается с reinterpret_cast
: мой совет на этот счет таков:
1. как правило, никогда ничего не бросайте к другому типу. Если типы не совпадают, то наиболее вероятной причиной является то, что (а) ваши переменные не были определены с правильным типом для начала, или(б) переменная или функция, которую вы пытаетесь использовать с вашей переменной, не была определена с правильным типом. Постарайтесь это исправить, если это возможно.
2. Если вы должны бросить, используйте const_cast
, dynamic_cast
, или static_cast
- в зависимости от того, что подходит.
3. Если ни одно из вышеперечисленных действий не работает, перепишите свою программу, чтобы полностью избежать приведения, или в худшем случае вам сойдет с рук случай 2. выше.
С помощью reinterpret_cast
это капитуляция: вы отказываетесь от статической типизации и всех сопутствующих ей преимуществ, заменяя ее управлением байт-потоками. Это может сработать, но только если вы полностью понимаете формат фактических данных и полностью контролируете управление ими. В данном случае у вас нет ни того, ни другого.
Исходя из этого, мое предложение состоит в том, чтобы решить эту проблему в соответствии с примером 3. выше: перепишите свою программу, то есть части, которые имеют дело с записью и чтением данных. Есть и другие функции, которые полностью способны писать и читать std::string
объекты, так что используйте их, а не двоичные выходные функции:
void write_sal(fstream& f, const sal& s) {
f << s.name << endl << s.y <<endl;
}
sal read_sal(fstream& f) {
sal s;
f >> s.name >> s.y;
return s;
}
Там. Кастинг не требуется. Я еще не проверял его: дополнительный
endl
то, что я добавил к выходу, может и не понадобиться, возможно, вам придется это проверить.
С. П.:
Потоковый оператор
operator>>(std::basic_string&)
будет считываться только до первого пробела. Поэтому, если ваши входные данные могут содержать пробелы, используйте эту функцию
std::basic_istream::getline()
вместо:
sal read_sal(fstream& f) {
sal s;
std::getline(f, s.name);
f >> s.y;
return s;
}
Теперь, если ваш объект sal
{ "What do you get if you multiply six by nine?" , 42 }
, то первая версия будет только читать
{ "What", 0 }
, в то время как приведенная выше модификация будет правильно читать полный текст и номер.
П. П. С.:
Я должен упомянуть, что смешивание различных методов чтения или записи из/в потоки может вызвать проблемы, поскольку они могут использовать различные методы синхронизации. Поэтому, чтобы быть в безопасности, было бы лучше изменить эту последнюю функцию чтения следующим образом:
sal read_sal(fstream& f) {
sal s;
std::getline(f, s.name);
std::string sy;
std::getline(f, sy);
s.y = std::stoi(sy);
return s;
}
Видеть
std:: getline - cppreference.com[
^]