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

时间:2018-01-04 15:24:14

标签: c++ string serialization boost

作为一项实验,我试图逐个(de)将std::map<std:string, ValueType>序列化为二进制文件,逐个元素。

我使用的是这样的东西:

Live on Wandbox

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时,相同的代码效果很好。

1 个答案:

答案 0 :(得分:3)

您保存int count;ia & count;,然后加载size_t:如果intia & key;的大小不同,则下一次加载(即第一次std::string } call)将被破坏;那么,我想bad_alloc加载器将读回错误的字符串大小,导致b被抛出。

奇怪的是,由于您的平台(联合国)幸运字节顺序和签名表示,计数数据结果只是偶然读取...

在基于文本的情况下,计数数据是以文本方式解析的,因此序列化可以顺利进行。

顺便说一句,IIRC标准容器和变体只要参数可以自动序列化,所以你不需要手工编写序列化代码......