program with boost::serialization

Aug 5, 2014 at 2:00pm
I am writing program with boost::serialization and output with text archive. after I write the object to a file, I cant read deserialize it correctly. The records being written into the file is different with the records being read out from the file. Is it a bug of boost or there is something wrong with my code. please, someone give me a hint. Thx! My program is as follows.
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <boost/serialization/map.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/version.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include "types.h"

using namespace std;
using namespace boost;
using namespace boost::serialization;
using namespace boost::archive;

int main(int argc,char ** argv)
{
	ofstream out("test.txt");
	if(false == out.is_open()) {
		cout<<"invalid file!"<<endl;
		return EXIT_FAILURE;
	}
	text_oarchive oa(out);
	map<Status,map<Action,double> > Q;
	for(int x1 = 1 ; x1 <= 7 ; x1++)
		for(int y1 = 1 ; y1 <= 6 ; y1++)
			for(int x2 = 1 ; x2 <= 7 ; x2++)
				  for(int y2 = 1 ; y2 <= 6 ; y2++)
					for(int g1 = 0 ; g1 < 3 ; g1++)
						  for(int g2 = 0 ; g2 < 3 ; g2++)
							for(int i = 0 ; i < 5 ; i++)	
								Q[Status(x1,y1,x2,y2,(Status::GraspState)g1,(Status::GraspState)g2)][(Action)i] = 0;
	//the records written into the file
	cout<<Q.size()<<endl;
	oa << Q;
	out.close();
	Q.clear();
	ifstream in("test.txt");
	text_iarchive ia(in);
	ia >> Q;
	//the records read from the file
	cout<<Q.size()<<endl;
}

types.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef TYPES_H
#define TYPES_H

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/version.hpp>

using namespace boost;
using namespace boost::serialization;

enum Action {LEFT = 0,RIGHT,UP,DOWN,STAND_STILL};
struct Status {
	  friend class boost::serialization::access;
	  template<class Archive> void serialize(Archive & ar,const unsigned int version) {}
  
	  int x1,y1,x2,y2;
	  enum GraspState {FREE = 0,GRASPING_LEFT,GRASPING_RIGHT} g1,g2;
	  Status() {}
	  Status(int xx1,int yy1,int xx2,int yy2,GraspState gg1,GraspState gg2) : x1(xx1),y1(yy1),x2(xx2),y2(yy2),g1(gg1),g2(gg2) {}
	  Status(const Status & q);
	  ~Status() {}
	  friend bool operator<(const Status& idx1,const Status & idx2);
	  friend bool operator==(const Status & idx1,const Status & idx2);
};

Status::Status(const Status & q)
{
          x1 = q.x1; y1 = q.y1; x2 = q.x2; y2 = q.y2; g1 = q.g1; g2 = q.g2;
}

bool operator<(const Status& idx1,const Status & idx2)
{
          if(idx1.x1 < idx2.x1) return true;
          if(idx1.x1 > idx2.x1) return false;
          if(idx1.y1 < idx2.y1) return true;
          if(idx1.y1 > idx2.y1) return false;
          if(idx1.x2 < idx2.x2) return true;
          if(idx1.x2 > idx2.x2) return false;
          if(idx1.y2 < idx2.y2) return true;
          if(idx1.y2 > idx2.y2) return false;
          if(idx1.g1 < idx2.g1) return true;
          if(idx1.g1 > idx2.g1) return false;
          if(idx1.g2 < idx2.g2) return true;
          if(idx1.g2 > idx2.g2) return false;
          return false;
}

bool operator==(const Status & idx1,const Status & idx2)
{
          return idx1.x1 == idx2.x1 && idx1.y1 == idx2.y1 && idx1.x2 == idx2.x2 && idx1.y2 == idx2.y2 && idx1.g1 == idx2.g1 && idx1.g2 == idx2.g2;
}

namespace boost {
	  namespace serialization {
			template<class Archive> inline void save_construct_data(Archive & ar, const Status * i, const unsigned int version) {
				  ar << i->x1 << i->y1 << i->x2 << i->y2 << i->g1 << i->g2;
			}
			template<class Archive> void load_construct_data(Archive & ar,Status * i, const unsigned int version) {
				  int x1,y1,x2,y2;
				  Status::GraspState g1,g2;
				  ar >> x1 >> y1 >> x2 >> y2 >> g1 >> g2;
				  ::new(i) Status(x1,y1,x2,y2,g1,g2);
			}
	  }
}

#endif 

Aug 6, 2014 at 12:07am
If you haven't already, give this page a read: http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/serialization.html

Salient points:
If your load and save functions are free functions then serialize needs to be a free function also, not a member function. http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/serialization.html#splittingfreefunctions

Note that although the functionality to split the serialize function into save/load has been provided, the usage of the serialize function with the corresponding & operator is preferred.
Aug 6, 2014 at 1:33am
the implement of serialize function follows the instruction given here http://www.boost.org/doc/libs/1_55_0/libs/serialization/doc/serialization.html#constructors . It does not mean to split the save and load functions.
Aug 6, 2014 at 2:35am
And what pointer is it that you are serializing?

Tried your code and it works fine for me with the following change:
1
2
3
4
template<class Archive> void serialize(Archive & ar,const unsigned int version) 
{
    ar & x1 & y1 & x2 & y2 & g1 & g2;
}
15876
15876
Aug 6, 2014 at 11:35am
thx, the problem is solved though I dont know why. I implemented the serialize function for non default constructor. I thought that was enough.
Topic archived. No new replies allowed.