std::vector<float> 成员的 boost 序列化/反序列化失败

Posted

技术标签:

【中文标题】std::vector<float> 成员的 boost 序列化/反序列化失败【英文标题】:boost serialization / Deserialization of std::vector<float> member fails 【发布时间】:2017-04-17 15:47:32 【问题描述】:

下午好,

我是第一次玩 boost::serialization,目前在一些非常基本的任务上失败了。我将我的代码简化为非常基本的,首先是一个只有一个 std::vector 成员的简单类的类定义:

#ifndef DATA_H
#define DATA_H

#include <string>
#include <vector>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

namespace ml 
    class Data 
        private:
            std::vector<float> d;

            friend class boost::serialization::access;

            template<class Archive>
            void serialize(Archive& ar, const unsigned int version);
        public:

            static Data Load(const std::string& filename);

            Data(const std::vector<float>& d);

            Data(const Data& rhs);
            Data();

            ~Data();

            Data& operator=(const Data& rhs);

            void save(const std::string& filename);

            std::vector<float> getD() const;
    ;

#endif // DATA_H 

实现:

#include <iostream>
#include <fstream>

#include <boost/serialization/vector.hpp>

#include "Data.h"

ml::Data::Data(const std::vector<float>& d) : d(d)



ml::Data::Data(const Data& rhs)

    d = rhs.d;


ml::Data::Data()




ml::Data& ml::Data::operator=(const Data& rhs)

    d = rhs.d;

    return *this;


ml::Data ml::Data::Load(const std::string& filename)

    Data data;

    std::ifstream file(filename.c_str());

    boost::archive::text_iarchive ia(file);

    ia >> data;

    return data;


ml::Data::~Data()



void ml::Data::save(const std::string& filename)

    std::ofstream file(filename.c_str());    

    boost::archive::text_oarchive oa(file);

    oa << this;


std::vector<float> ml::Data::getD() const

   return d;


template<class Archive>
void ml::Data::serialize(Archive& ar, const unsigned int version)

   ar & d;

   std::cout << "Debug: " << d.size() << std::endl;

还有一个非常小的主程序:

#include <iostream>

#include "Data.h"

int main(int argc, char** argv)

    const std::string filename("./test.txt");
    const int limit = 100;

    std::vector<float> orig;
    std::vector<float> copy;

    for(int i=0; i<limit; ++i) 
        orig.push_back(i);
    

    ml::Data origData(orig);
    origData.save(filename);

    ml::Data copyData = ml::Data::Load(filename);

    orig = origData.getD();
    copy = copyData.getD();

    std::cout << "Sizes: "    << std::endl;
    std::cout << "Original: " << orig.size() << std::endl;
    std::cout << "Copy: "     << copy.size() << std::endl;

    return 0;

程序输出为:

Debug: 100 
Debug: 0 
Sizes:  
Original: 100 
Copy: 0

序列化和文件输出似乎工作,生成的文件看起来如预期,但反序列化似乎失败。没有进一步的错误输出或任何提示,出了什么问题。如果感兴趣的话,Boost 版本是 1.60.0。

那么,你知道出了什么问题吗?

提前谢谢你。

【问题讨论】:

【参考方案1】:

您的序列化将指针序列化:

oa << this;

反序列化反序列化为引用:

Data data;
ia >> data;

这是一个错误。结果未定义。修复它:

oa << *this;

演示

Live On Coliru

打印:

Debug (loading: false) 5
Original: 5
Debug (loading: true) 5
Copy: 5

代码:

#ifndef DATA_H
#define DATA_H

#include <string>
#include <vector>

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

namespace ml 
    class Data 
        private:
            std::vector<float> d;

            friend class boost::serialization::access;

            template<class Archive>
            void serialize(Archive& ar, const unsigned int version);
        public:

            static Data Load(const std::string& filename);

            Data(const std::vector<float>& d) : d(d) 
            //Data(const Data& rhs) = default;
            Data() = default;
            //~Data() = default;
            //Data& operator=(const Data& rhs) = default;

            void save(const std::string& filename);

            std::vector<float> getD() const;
    ;

#endif // DATA_H 

#include <iostream>
#include <fstream>

#include <boost/serialization/vector.hpp>

//#include "Data.h"
ml::Data ml::Data::Load(const std::string& filename)

    Data data;

    std::ifstream file(filename.c_str());

    boost::archive::text_iarchive ia(file);

    ia >> data;

    return data;


void ml::Data::save(const std::string& filename)

    std::ofstream file(filename.c_str());    

    boost::archive::text_oarchive oa(file);

    oa << *this;


std::vector<float> ml::Data::getD() const

   return d;


template<class Archive>
void ml::Data::serialize(Archive& ar, const unsigned int /*version*/)

   ar & d;

   std::cout << "Debug (loading: " << std::boolalpha << typename Archive::is_loading::type() << ") " << d.size() << std::endl;


#include <iostream>

int main()

    const std::string filename("./test.txt");
    const int limit = 5;

    
        std::vector<float> orig;

        for(int i=0; i<limit; ++i)  orig.push_back(i); 

        ml::Data origData(orig);
        origData.save(filename);

        orig = origData.getD();
        std::cout << "Original: " << orig.size() << std::endl;
    

    ml::Data copyData = ml::Data::Load(filename);
    std::cout << "Copy: " << copyData.getD().size() << std::endl;

【讨论】:

谢谢,虽然很简单,但我看不到。现在可以了。

以上是关于std::vector<float> 成员的 boost 序列化/反序列化失败的主要内容,如果未能解决你的问题,请参考以下文章

如何将 std::vector<float> 转换为浮点数组? [复制]

std::vector<float> 成员的 boost 序列化/反序列化失败

c ++两个线程之间更快的变量交换一个std :: vector <float *>和array

在 std::vector 上的 Openmp 和缩减?

如何使用可变长度类型将包含多个 std::vector<float> 的结构写出到 HDF5?

正确分配 std::vector