Я не могу воспроизвести его с помощью следующего кода (это просто ваш код, созданный для компиляции и добавления некоторых изменений стиля / вывода).
Если у вас все еще есть «cra sh», тогда он должен происходят из другого места. Вероятно, объект проигрывателя устарел (вы действительно передаете его по ссылке или по указателю в своем коде?).
Вы можете использовать Asan / UBSan для поиска подобных ошибок. Кроме того, valgrind.
В противном случае, опубликуйте автономную программу, которая демонстрирует cra sh.
DEMO TIME
Смотрите здесь живую демонстрацию, в которой реализованы счастье и ошибка. пути:
Live On Coliru
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/serialization/string.hpp>
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
class Player {
public:
Player() = default;
Player(std::string name, unsigned short level, int money, float stealth)
: name_(std::move(name)), level_(level), money_(money),
stealth_(stealth) {}
// ... Getter and setters ...
private:
friend class boost::serialization::access;
friend std::ostream& operator<<(std::ostream& os, Player const& player) {
return os << "Player {" << std::quoted(player.name_)
<< ", level:" << player.level_ << ", money:" << player.money_
<< ", stealth:" << player.stealth_ << " }";
}
std::string name_;
unsigned short level_;
int money_;
float stealth_;
template <class Archive>
/**
Used for Boost library data serialization
@param ar Archive reference
@param version Unused variable needed for Boost compatibility
*/
void serialize(Archive& ar, unsigned /*unused*/) {
ar& name_& level_& money_& stealth_;
}
public:
/**
Searches for a player's save file in a directory
@param player_name The name of the player
@param save_dir The directory to search for the player's save file
@returns 'true' if the player's save file is found; 'false' otherwise
*/
static bool exists(const std::string& player_name,
const std::filesystem::path& save_dir) {
return fs::exists((save_dir / player_name).replace_extension(".dat"));
}
};
struct {
static std::string get_value() { return "player_name"; }
} static login_menu;
namespace cons {
namespace fopenmode {
static auto const input = std::ios::in;
}
struct File {
std::string fname;
std::ifstream ifs;
File(std::string fname, std::ios::openmode mode)
: fname(fname), ifs(fname, mode) {
ifs.exceptions(std::ios::badbit | std::ios::failbit);
}
auto& get_ifstream() { return ifs; }
bool delete_file() {
if (ifs.is_open()) {
ifs.close();
}
return fs::remove(fname);
}
};
template <typename... T> void print(T const&... v) {
for (auto&& frag : { boost::lexical_cast<std::string>(v)... }) {
std::cout << frag << std::endl;
}
}
void pause() {
std::cout << "(press Enter to continue)\n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} // namespace cons
int main() {
// Inside the main function
const auto player_name = login_menu.get_value();
auto const sav_dir = fs::current_path() / "sav";
fs::create_directories(sav_dir);
auto const fname = (sav_dir / player_name).replace_extension(".dat");
if (Player::exists(player_name, sav_dir)) {
std::cout << "Opening existing file " << fname << "\n";
cons::File player_file(fname, cons::fopenmode::input);
try {
boost::archive::text_iarchive player_file_archive(
player_file.get_ifstream());
Player player;
player_file_archive >> player;
std::cout << "Player: " << player << "\n";
} catch (std::exception const& e) {
cons::print(e.what(),
"ERROR: Save file was located, but cannot be loaded.",
"It may be corrupted. Deleting save file.");
cons::pause();
player_file.delete_file();
}
}
if (!Player::exists(player_name, sav_dir))
{ // No player found; make new player
std::cout << "Creating save file " << fname << "\n";
Player player(player_name, 1, 0, 1.0f);
std::ofstream player_file(fname);
{ // Create new save file
boost::archive::text_oarchive player_file_archive(player_file);
player_file_archive << player;
}
}
}
Выполнение
g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp -lboost_serialization -o test.exe
(./test.exe; ./test.exe; sed -i 's/serializa/corrup/' sav/*; ./test.exe; ./test.exe) < /dev/null
head sav/*
Печать
Creating save file "/tmp/1587589055-765971644/sav/player_name.dat"
Opening existing file "/tmp/1587589055-765971644/sav/player_name.dat"
Player: Player {"player_name", level:1, money:0, stealth:1 }
Opening existing file "/tmp/1587589055-765971644/sav/player_name.dat"
invalid signature
ERROR: Save file was located, but cannot be loaded.
It may be corrupted. Deleting save file.
(press Enter to continue)
Creating save file "/tmp/1587589055-765971644/sav/player_name.dat"
Opening existing file "/tmp/1587589055-765971644/sav/player_name.dat"
Player: Player {"player_name", level:1, money:0, stealth:1 }
22 serialization::archive 17 0 0 11 player_name 1 0 1.000000000e+00