升压系列化,原C数组的反序列化 [英] boost serialization, deserialization of raw C arrays

查看:113
本文介绍了升压系列化,原C数组的反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想序列化和反序列化原料C指针及其数据,与下面的例子。这似乎序列化就好了,但我不确定如何让它反序列化 - 它只是一个内存访问冲突异常崩溃,当我反序列化。我想这是因为它不到风度知道如何反序列化,但我在哪里指定?

使用向量是不是一种选择,在非常大的原始数据量是非常缓慢

 的#include< stdint.h>
#包括LT&;串GT;
#包括LT&;&iostream的GT;
#包括LT&;&的fstream GT;
#pragma警告(推)
#pragma警告(禁用:4244)
#包括LT&;升压/系列化/ serialization.hpp>
#包括LT&;升压/系列化/ vector.hpp>
#包括LT&;升压/系列化/ string.hpp>
#包括LT&;升压/系列化/ array.hpp>
#包括LT&;升压/存档/ binary_oarchive.hpp>
#包括LT&;升压/存档/ binary_iarchive.hpp>
#pragma警告(POP)结构猴
{
    uint32_t的NUM;
    浮动* ARR;};
名字空间boost
{
    命名空间序列化
    {
        模板<类归档和GT;
        无效连载(归档和放大器; AR,猴安培;男,const的无符号整型版)
        {
            AR&安培; m.num;
            AR&安培; make_array<浮动>(m.arr,m.num);
        }
    }
}
INT _tmain(INT ARGC,_TCHAR *的argv [])
{
    为const char * name =monkey.txt;    {
        猴子米;
        m.num = 10;
        m.arr =新的浮动[m.num]
        对于(uint32_t的指数= 0;指数 - LT; m.num;指数++)
            m.arr [指数] =(浮点)指数;        的std :: ofstream的outStream(名称,标准::内部监督办公室::出来|的std :: IOS ::二进制|性病:: IOS :: TRUNC);
        提高::档案:: binary_oarchive桨(outStream);
        桨<< (米);
    }    猴子米;
    性病:: ifstream的inStream中(名称,标准::内部监督办公室::在|的std :: IOS ::二进制);
    提高::档案:: binary_iarchive IAR(插播广告);
    IAR>> (米);    返回0;
}


解决方案

我衷心建议您使用的std ::阵列的std ::矢量在这里,因为......你搞砸这件事:)

对于初学者来说,不其成员初始化。因此,装载结束了做一个 load_binary 到任何指针值 m.arr 碰巧有。你会如何​​期待反序列化到知道你需要为分配内存?你需要的告诉它的:

 模板<类归档和GT;
    无效连载(归档和放大器; AR,猴安培;男,const的无符号整型版)
    {
        AR&安培; m.num;
        如果(归档:: is_loading ::值)
        {
            断言(m.arr == nullptr);
            m.arr =新的浮动[m.num]
        }
        AR&安培; make_array<浮动>(m.arr,m.num);
    }

现在,让我们少了几分不安全的(通过增加初始化和破坏,也许最重要的是,禁止拷贝语义):

 结构猴
{
    uint32_t的NUM;
    浮动* ARR;    猴子():NUM(0U),编曲(nullptr){}    猴(猴常量和放大器;)=删除;
    猴放大器;运算符=(const的猴子和安培)=删除;
    〜猴(){删除[] ARR; }
};

现在,你可以看到它的工作:

 的#include<&iostream的GT;
#包括LT&;&的fstream GT;
#pragma警告(禁用:4244)
#包括LT&;升压/系列化/ serialization.hpp>
#包括LT&;升压/存档/ binary_oarchive.hpp>
#包括LT&;升压/存档/ binary_iarchive.hpp>结构猴
{
    uint32_t的NUM;
    浮动* ARR;    猴子():NUM(0U),编曲(nullptr){}    猴(猴常量和放大器;)=删除;
    猴放大器;运算符=(const的猴子和安培)=删除;
    〜猴(){删除[] ARR; }
};名字空间boost
{
    命名空间序列化
    {
        模板<类归档和GT;
        无效连载(归档和放大器; AR,猴安培;男,const的无符号整型版)
        {
            AR&安培; m.num;
            如果(归档:: is_loading ::值)
            {
                断言(m.arr == nullptr);
                m.arr =新的浮动[m.num]
            }
            AR&安培; make_array<浮动>(m.arr,m.num);
        }
    }
}INT主(INT ARGC,CHAR *的argv [])
{
    为const char * name =monkey.txt;
    {
        猴子米;
        m.num = 10;
        m.arr =新的浮动[m.num]
        对于(uint32_t的指数= 0;指数 - LT; m.num;指数++)
            m.arr [指数] =(浮点)指数;        的std :: ofstream的outStream(名称,标准::内部监督办公室::出来|的std :: IOS ::二进制|性病:: IOS :: TRUNC);
        提高::档案:: binary_oarchive桨(outStream);
        桨<< (米);
    }    猴子米;
    性病:: ifstream的inStream中(名称,标准::内部监督办公室::在|的std :: IOS ::二进制);
    提高::档案:: binary_iarchive IAR(插播广告);
    IAR>> (米);    性病::复制(m.arr,m.arr + m.num,的std :: ostream_iterator<浮动>(STD ::法院,));
}

打印

  0; 1; 2; 3; 4; 5; 6; 7; 8; 9;

住在Coliru

I'm trying to serialize and deserialize raw C pointers and their data, with the example below. It seems to serialize just fine, but I am unsure how to make it deserialize - it just crashes with a memory access violation exception when I deserialize it. I suppose it is because it dosn't know how to deserialize it, but where do I specify that?

Using a vector is not an option, in very large primitive data amounts it is painfully slow

#include <stdint.h>
#include <string>
#include <iostream>
#include <fstream>
#pragma warning (push) 
#pragma warning( disable : 4244 ) 
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/array.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#pragma warning (pop) 

struct Monkey
{
    uint32_t num;
    float* arr;

};


namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void serialize(Archive & ar, Monkey& m, const unsigned int version)
        {
            ar & m.num;
            ar & make_array<float>(m.arr, m.num);
        }
    }
}


int _tmain(int argc, _TCHAR* argv[])
{
    const char* name = "monkey.txt";

    {
        Monkey m;
        m.num = 10;
        m.arr = new float[m.num];
        for (uint32_t index = 0; index < m.num; index++)
            m.arr[index] = (float)index;

        std::ofstream outStream(name, std::ios::out | std::ios::binary | std::ios::trunc);
        boost::archive::binary_oarchive oar(outStream);
        oar << (m);
    }

    Monkey m;
    std::ifstream inStream(name, std::ios::in | std::ios::binary);     
    boost::archive::binary_iarchive iar(inStream);
    iar >> (m);

    return 0;
}

解决方案

I heartily recommend you use std::array or std::vector here, because... you messed this up :)

For starters, Monkey doesn't initialize its members. So, loading ends up doing a load_binary to whatever pointer value m.arr happened to have. How would you expect the deserialization to "know" that you needed to allocate memory for that? You need to tell it:

    template<class Archive>
    void serialize(Archive & ar, Monkey& m, const unsigned int version)
    {
        ar & m.num;
        if (Archive::is_loading::value)
        {
            assert(m.arr == nullptr);
            m.arr = new float[m.num];
        }
        ar & make_array<float>(m.arr, m.num);
    }

Now, let's make Monkey a bit less unsafe (by adding initialization and destruction, and, perhaps most importantly, prohibiting copy semantics):

struct Monkey
{
    uint32_t num;
    float* arr;

    Monkey() : num(0u), arr(nullptr) {}

    Monkey(Monkey const&) = delete;
    Monkey& operator=(Monkey const&) = delete;
    ~Monkey() { delete[] arr; }
};

Now, you can see it work:

#include <iostream>
#include <fstream>
#pragma warning(disable: 4244)
#include <boost/serialization/serialization.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

struct Monkey
{
    uint32_t num;
    float* arr;

    Monkey() : num(0u), arr(nullptr) {}

    Monkey(Monkey const&) = delete;
    Monkey& operator=(Monkey const&) = delete;
    ~Monkey() { delete[] arr; }
};

namespace boost
{
    namespace serialization
    {
        template<class Archive>
        void serialize(Archive & ar, Monkey& m, const unsigned int version)
        {
            ar & m.num;
            if (Archive::is_loading::value)
            {
                assert(m.arr == nullptr);
                m.arr = new float[m.num];
            }
            ar & make_array<float>(m.arr, m.num);
        }
    }
}

int main(int argc, char* argv[])
{
    const char* name = "monkey.txt";
    {
        Monkey m;
        m.num = 10;
        m.arr = new float[m.num];
        for (uint32_t index = 0; index < m.num; index++)
            m.arr[index] = (float)index;

        std::ofstream outStream(name, std::ios::out | std::ios::binary | std::ios::trunc);
        boost::archive::binary_oarchive oar(outStream);
        oar << (m);
    }

    Monkey m;
    std::ifstream inStream(name, std::ios::in | std::ios::binary);
    boost::archive::binary_iarchive iar(inStream);
    iar >> (m);

    std::copy(m.arr, m.arr + m.num, std::ostream_iterator<float>(std::cout, ";"));
}

Prints

0;1;2;3;4;5;6;7;8;9;

Live on Coliru

这篇关于升压系列化,原C数组的反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆