从 boost::存档:binary_iarchive 反序列化 std::string 时出现错误的分配异常

Bad allocation exception when deserializing std::string from boost::archive:binary_iarchive

本文关键字:错误 异常 分配 string std 存档 boost binary 反序列化 iarchive      更新时间:2023-10-16

作为一个实验,我正在尝试逐个元素地(反(序列化二进制文件的std::map<std:string, ValueType>

我正在使用这样的东西:

住在魔杖盒上

void Save(const std::string& fname, const MapType& c)
{
    std::ofstream f(fname.c_str(), std::ios::binary);
    boost::archive::binary_oarchive oa(f, boost::archive::no_header);
    oa & c.size();
    for (auto& e : c)
    {
        oa & e.first;
        oa & e.second;
    }
}
void Load(const std::string& fname, MapType& c)
{
    std::ifstream f(fname.c_str(), std::ios::binary);
    boost::archive::binary_iarchive ia(f, boost::archive::no_header);
    int count;
    ia & count;
    for (int i = 0; i < count; ++i)
    {
        std::string key;
        ValueType value;
        ia & key;
        ia & value;
        c[key] = value;
    }
}

顺便说一下:

using ValueType = boost::variant<bool, int, double, std::string>;
using MapType = std::map<std::string, ValueType>;

保存后,我重新加载文件。count读取正确,但第一个key给出错误的分配异常。

有什么想法吗?

当我将binary_oarchivebinary_iarchive替换为它们各自的文本等效项时,相同的代码效果很好。

你保存oa & c.size();然后加载int count;ia & count;:如果碰巧size_tint的大小不同,下一次加载(即第一次ia & key;调用(将被破坏; 然后,我猜std::string加载器会读回错误的字符串大小,导致抛出bad_alloc

奇怪的是,计数数据结果只是偶然正确读取,由于您的平台(不(幸运的字节序和有符号表示......

在基于文本的情况下,计数数据以文本方式解析,因此序列化不会出错。

顺便说一下,IIRC 标准容器和变体在其参数存在时都可以自动序列化,因此您无需手动编写它们的序列化代码......