Reputation: 1739
Good afternoon,
I'm playing around with boost::serialization for the first time and am currently failing with some very basic task. I stripped down my code to the very basic, first the class defininiton for a simple class with just one std::vector member:
#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
The implementation:
#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;
}
And a very small main program:
#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;
}
The program output is:
Debug: 100
Debug: 0
Sizes:
Original: 100
Copy: 0
Serialization and file output seem to work, the resulting file looks as expected, but de-serialization seems to fail. There is no further error output or any hint, what goes wrong. Boost version is 1.60.0 if that is of interest.
So, any idea what is going wrong?
Thank you in advance.
Upvotes: 0
Views: 982
Reputation: 393934
Your serialization serializes a pointer:
oa << this;
The deserialization deserializes into a reference:
Data data;
ia >> data;
That's a bug. The result is undefined. Fix it:
oa << *this;
Prints:
Debug (loading: false) 5
Original: 5
Debug (loading: true) 5
Copy: 5
Code:
#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;
}
Upvotes: 2