C++使用Boost二进制反序列化加载D&D引擎角色数据触发异常
核心问题排查
共4处关键错误直接导致异常和数据错乱:
- 读写逻辑结构完全不匹配:保存时序列化了整个
Character对象指针this,包含Boost序列化自动添加的对象头信息,加载时却手动逐个读取成员变量,没有对应头信息解析步骤,直接导致数据流错位。 - 文件流未开启二进制模式:使用
binary_oarchive/binary_iarchive时,配套的文件流必须添加std::ios::binary打开标志,否则默认文本模式下系统会自动转义换行等控制字符,直接破坏二进制序列化数据。 - 序列化
Stats的类型不匹配:Character的serialize方法中序列化的是解引用后的*charStats(Stats对象),但加载逻辑中直接读取到Stats*指针,Boost序列化指针时会额外存储指针跟踪标记,和对象序列化的数据结构完全不同。 Character的serialize方法仅支持写入:你使用了<<运算符仅支持序列化写入,反序列化读取时调用该方法会直接报错,需要换成双向兼容的&运算符。
修复方案
推荐使用更简洁的全对象统一序列化逻辑,修改后代码如下:
1. 修改Character.hpp中的serialize方法
template<class Archive> void serialize(Archive& ar, const unsigned int version) { ar & name; ar & *charStats; ar & inventory; }
2. 修改Character.cpp中的saveCharacter方法
void Character::saveCharacter() { std::string fileName = name + ".dat"; // 新增二进制打开标志 std::ofstream saveFile(fileName, std::ios::binary); boost::archive::binary_oarchive outputArchive(saveFile); // 序列化对象本身而非指针,避免额外的指针跟踪开销 outputArchive << *this; saveFile.close(); }
3. 修改Character.cpp中的loadCharacter方法
void Character::loadCharacter(std::string &charName) { std::string fileName = charName + ".dat"; // 新增二进制打开标志 std::ifstream loadFile(fileName, std::ios::binary); boost::archive::binary_iarchive inputArchive(loadFile); // 直接读取整个对象到当前实例,不需要手动拆分成员 inputArchive >> *this; loadFile.close(); }
额外优化建议
- 给
Character添加析构函数释放charStats指针,避免内存泄漏,或者直接改用std::unique_ptr<Stats>替代裸指针,Boost序列化默认支持智能指针。 - 加载前需要先确保
charStats已经初始化分配了内存,避免解引用空指针。
内容的提问来源于stack exchange,提问作者dmsokol13
相关产品推荐
相关产品推荐

