Hello !
Alors je continue dans ce post ...
J'ai jeté un oeil a cette "bibliothèque" (lib...) et ça m'a l'air pas si mal.
J'ai commencé à sérialiser ma structure depuis le bas.
Je rencontre cependant quelques problèmes pour sérialiser mon tableau bi-dimensionnel (Cell** m_cells).
Je vois bien que c'est un problème de mémoire (pointeurs) mais je n'arrive pas à comprendre pourquoi ... peut-être l'un de vous pourra m'expliquer.
A noter que j'ai mis en rouge dans l'output ce qui pose problüme.
En gros, lorsque je charge mon tableau depuis le fichier, il "ecrase" les autres tableaux. Je pense qu'il le charge en "overlapant" sur leurs emplacmement mémoire ...
A noter également que je transforme mon tableau2D en 1D (flatten) avant de le sérialiser puis que j'effectue l'opération inverse juste aprüs l'avoir chargé (unflatten). Si quelqu'un connait une solution plus élégante je suis preneur ...
Voici le code et l'output:
#include
#include
#include
#include <sstream>
#include <fstream>
#include
#include
#include
using namespace std;
using namespace boost::archive;
using namespace boost::serialization;
/*
* point
*
*/
template <class T> struct point{
inline point():x(0),y(0) {}
inline point(T _x, T _y):x(_x),y(_y){}
T x, y;
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, const unsigned int version){
ar & x & y;
}
};
/*
* PointAccumulator
*
*/
struct PointAccumulator{
typedef point<float> FloatPoint;
PointAccumulator(): acc(0,0), n(0), visits(0){}
PointAccumulator(int i): acc(0,0), n(0), visits(0){assert(i==-1);}
//PointAccumulator& operator=(const PointAccumulator & pa);
static PointAccumulator* unknown_ptr;
FloatPoint acc;
int n, visits;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive& ar, const unsigned int version){
ar & n & visits & acc;
}
};
/*
PointAccumulator& PointAccumulator::operator=(const PointAccumulator &pa){
acc = point<float>(pa.acc.x,pa.acc.y);
n = pa.n;
visits = pa.visits;
cout << "copied pa " << acc.x << endl;
return *this;
}
*/
/*
* Array2D
*
*/
template<class Cell, const bool debug=false> class Array2D{
public:
Array2D(int xsize=0, int ysize=0);
Array2D& operator=(const Array2D &);
Array2D(const Array2D<Cell,debug> &);
void clear();
//inline Array2D(int xsize, int ysize, const Cell * flatCells): m_cells(flatCells), m_ysize(ysize), m_xsize(xsize){}
void flatten();
void unflatten();
//~Array2D();
inline Cell& cell(int x, int y);
inline void print(){
cout << "Displaying array2D (x,y) --> (" << m_xsize << "," << m_ysize << ")" << " as (n,visits,acc.x,acc.y)" << endl;
for(int i=0;i<m_xsize;i++){
for(int j=0;j<m_ysize;j++){
cout << "(" << cell(i,j).n << "," << cell(i,j).visits << "," << cell(i,j).acc.x << "," << cell(i,j).acc.y << ") ";
}
cout<<endl;
}
/*cout << "flattened: " << endl;
for(int i=0;i<m_xsize*m_ysize;i++){
cout << "acc.x: " << m_cells1D[i].acc.x << " acc.visits: " << m_cells1D[i].visits << " ";
}*/
cout << endl;
}
Cell ** m_cells;
Cell * m_cells1D;
protected:
int m_xsize, m_ysize;
friend class boost::serialization::access;
template <class Archive> void serialize(Archive& ar, const unsigned int version){
ar & m_xsize & m_ysize;
for(int i=0; i<m_xsize*m_ysize;i++){
ar & m_cells1D[i];
}
}
};
template <class Cell, const bool debug>
Array2D<Cell,debug> & Array2D<Cell,debug>::operator=(const Array2D<Cell,debug> & g){
if (debug || m_xsize!=g.m_xsize || m_ysize!=g.m_ysize){
for (int i=0; i<m_xsize; i++)
delete [] m_cells[i];
delete [] m_cells;
m_xsize=g.m_xsize;
m_ysize=g.m_ysize;
m_cells=new Cell*[m_xsize];
for (int i=0; i<m_xsize; i++)
m_cells[i]=new Cell[m_ysize];
}
for (int x=0; x<m_xsize; x++)
for (int y=0; y<m_ysize; y++)
m_cells[x][y]=g.m_cells[x][y];
if (debug){
std::cerr << __PRETTY_FUNCTION__ << std::endl;
std::cerr << "m_xsize= " << m_xsize<< std::endl;
std::cerr << "m_ysize= " << m_ysize<< std::endl;
}
return *this;
}
template <class Cell, const bool debug>
Array2D<Cell,debug>::Array2D(int xsize, int ysize){
// assert(xsize>0);
// assert(ysize>0);
m_xsize=xsize;
m_ysize=ysize;
if (m_xsize>0 && m_ysize>0){
m_cells=new Cell*[m_xsize];
for (int i=0; i<m_xsize; i++)
m_cells[i]=new Cell[m_ysize];
}
else{
m_xsize=m_ysize=0;
m_cells=0;
}
if (debug){
std::cerr << __PRETTY_FUNCTION__ << std::endl;
std::cerr << "m_xsize= " << m_xsize<< std::endl;
std::cerr << "m_ysize= " << m_ysize<< std::endl;
}
}
template <class Cell, const bool debug>
inline Cell& Array2D<Cell,debug>::cell(int x, int y){
return m_cells[x][y];
}
template <class Cell, const bool debug>
Array2D<Cell,debug>::Array2D(const Array2D<Cell,debug> & g){
m_xsize=g.m_xsize;
m_ysize=g.m_ysize;
m_cells=new Cell*[m_xsize];
for (int x=0; x<m_xsize; x++){
m_cells[x]=new Cell[m_ysize];
for (int y=0; y<m_ysize; y++)
m_cells[x][y]=g.m_cells[x][y];
}
if (debug){
std::cerr << __PRETTY_FUNCTION__ << std::endl;
std::cerr << "m_xsize= " << m_xsize<< std::endl;
std::cerr << "m_ysize= " << m_ysize<< std::endl;
}
}
template <class Cell, const bool debug>
void Array2D<Cell,debug>::clear(){
if (debug){
std::cerr << __PRETTY_FUNCTION__ << std::endl;
std::cerr << "m_xsize= " << m_xsize<< std::endl;
std::cerr << "m_ysize= " << m_ysize<< std::endl;
}
for (int i=0; i<m_xsize; i++){
delete [] m_cells[i];
m_cells[i]=0;
}
delete [] m_cells;
m_cells=0;
delete [] m_cells1D;
m_cells1D = 0;
m_xsize =0;
m_ysize =0;
}
template <class Cell, const bool debug>
void Array2D<Cell,debug>::flatten(){
m_cells1D=new Cell[m_ysize*m_xsize];
for (int x=0; x<m_xsize; x++){
for (int y=0; y<m_ysize; y++)
m_cells1D[x*m_ysize+y]= m_cells[x][y];
}
}
template <class Cell, const bool debug>
void Array2D<Cell,debug>::unflatten(){
m_cells=new Cell*[m_xsize];
for (int x=0; x<m_xsize; x++){
m_cells[x]=new Cell[m_ysize];
for (int y=0; y<m_ysize; y++)
m_cells[x][y]= m_cells1D[x*m_ysize+y];
}
}
/*
* SaveToFile and LoadFromFile
*
*/
template <class A> void saveIntoFile(Array2D& array, const char* file){
ofstream ofile(file);
A ar(ofile);
ar << array;
ofile.close();
}
template <class A> void loadFromFile(Array2D& array, const char* file){
ifstream ifile(file);
A ar(ifile);
ar >> array;
ifile.close();
//return array;
}
/*
* MAIN
*
*/
int main(){
Array2D myArr = Array2D(2,2);
myArr.cell(0,0).acc.x = 3;
myArr.cell(0,0).n = 15;
myArr.cell(0,0).visits =16;
myArr.cell(0,1).acc.x = 3;
myArr.cell(0,1).n = 17;
myArr.cell(0,1).visits = 18;
myArr.cell(1,0).acc.x = 3;
myArr.cell(1,1).n = 20;
myArr.cell(1,1).visits = 21;
myArr.cell(1,1).acc.x = 22;
myArr.cell(1,1).acc.y = 23;
myArr.flatten();
cout << "myArray (toSave)" << endl;
myArr.print();
saveIntoFile<text_oarchive>(myArr,"out.txt");
Array2D myArr4 = Array2D();
myArr4 = myArr;
//Destroy myArr
myArr.clear();
cout << "myArray copy" << endl;
myArr4.print();
Array2D myArr2; // = Array2D();
loadFromFile<text_iarchive>(myArr2,"out.txt");
myArr2.unflatten();
cout << "myArray2 (loaded)" << endl;
myArr2.print();
//myArr2 = myArr4;
cout << "myArray (base)" << endl;
myArr.print();
cout << "myArray copy" << endl;
myArr4.print();
cout << "myArray2" << endl;
myArr2.print();
//myArr2.clear();
cout << "end" << endl;
return 0;
}
Output:
wheelchair@wheelchair-laptop:~/playerstage/boostTest$ g++ simple2.cpp -o simple -lboost_serialization
wheelchair@wheelchair-laptop:~/playerstage/boostTest$ ./simple
myArray (toSave)
Displaying array2D (x,y) --> (2,2) as (n,visits,acc.x,acc.y)
(15,16,3,0) (17,18,3,0)
(0,0,3,0) (20,21,22,23)
myArray copy
Displaying array2D (x,y) --> (2,2) as (n,visits,acc.x,acc.y)
(15,16,3,0) (17,18,3,0)
(0,0,3,0) (20,21,22,23)
myArray2 (loaded)
Displaying array2D (x,y) --> (2,2) as (n,visits,acc.x,acc.y)
(15,16,3,0) (17,18,3,0)
(0,0,3,0) (20,21,22,23)
myArray (base)
Displaying array2D (x,y) --> (0,17) as (n,visits,acc.x,acc.y)
myArray copy
Displaying array2D (x,y) --> (0,15) as (n,visits,acc.x,acc.y)
myArray2
Displaying array2D (x,y) --> (2,2) as (n,visits,acc.x,acc.y)
(15,16,3,0) (17,18,3,0)
(0,0,3,0) (20,21,22,23)
end
Segmentation fault
wheelchair@wheelchair-laptop:~/playerstage/boostTest$