Question

I am trying to serialize a member of a derived class. This member is inherited from a base class. The serialization code is included non-intrusively as part of the base class header file. The save(), load() methods are part of the base class implementation. I getting the following error when trying to run my code:

boost::archive::archive_exception' what(): input stream error

Here is the relevant part of the code:

ModelLibrary.h (This s the Base Class)

#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/set.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/list.hpp>
#include <fstream>

class ModelLibrary() 
{
    typedef std::pair<const ORROctree::Node::Data*, const ORROctree::Node::Data*>  Dipole;
    struct Base {
        Dipole seg1;
        Dipole seg2;
    };
    typedef std::list<Base> bases_list;
    typedef std::map <string, bases_list> SerializeHashTableCell;
    typedef NDIMVoxelStructure<SerializeHashTableCell> SerializeHashTable;

public:
    bool
    saveHashTable();

    bool
    loadHashTable();

    virtual bool
    generateHashTableArchiveName (string &filename) = 0;

public:
    SerializeHashTable shash_table_;  /***** MEMBER TO BE SERIALIZED ******/

};

// SERIALIZATION METHODS FOR THE TYPES USED TO FORM THE SERIALIZEHASHTABLE
namespace boost {
namespace serialization {

template<class Archive>
inline void serialize(Archive & ar, ModelLibrary::SerializeHashTable & h, const unsigned int version)
{
  for(int i = 0; i < h.total_num_of_voxels_; ++i)
    ar & h.voxels_[i];
  ar & h.num_of_voxels_;
  ar & h.total_num_of_voxels_i_;
  ar & h.bounds_;
  ar & h.spacing_;
  ar & h.min_center_;
}


template<class Archive>
inline void serialize(Archive & ar, ModelLibrary::Base & b, const unsigned int version)
{
  ar & b.seg1;
  ar & b.seg2;
}


template<class Archive>
inline void serialize(Archive & ar, ORROctree::Node n, const unsigned int version)
{
  ar & n.data_;
  ar & n.center_;
  ar & n.bounds_;
  ar & n.radius_;
  ar & n.parent_;
  ar & n.children_;
}

template<class Archive>
inline void serialize(Archive & ar, ORROctree::Node::Data d, const unsigned int version)
{
  ar & d.id_x_;
  ar & d.id_y_;
  ar & d.id_z_;
  ar & d.neighbors_;
  ar & d.lin_id_;
  ar & d.num_points_;
  ar & d.p_;

}`
} // namespace serialization
} // namespace boost

ModelLibrary.cpp

bool
ModelLibrary::saveHashTable ()
{
  string filename;
  generateHashTableArchiveName (filename);
  cout << "archive filename" << filename;
  std::ofstream ofs(filename.c_str());
  boost::archive::text_oarchive oa(ofs);
  // write class instance to archive
  oa << shash_table_;
  // archive and stream closed when destructors are called
  return true;
}


bool
ModelLibrary::loadHashTable ()
{
  string filename;
  generateHashTableArchiveName (filename);
  std::ifstream ifs(filename.c_str());
  boost::archive::text_iarchive ia(ifs);
  ia >> shash_table_;
  return true;
}

ModelLibraryG4PCS.h

class ModelLibraryG4PCS: public ModelLibrary
{
virtual bool
generateHashTableArchiveName (string &filename);

}

ModelLibrary4GPCS.cpp

bool
ModelLibraryG4PCS::generateHashTableArchiveName (string &filename)
{
  filename = "";
  //Concatenate all Added Models into filename
  std::map<std::string, Model*>::const_iterator model_itr = models_.begin();
  for (; model_itr != models_.end(); ++model_itr)
  {
    filename += model_itr->first;
  }

  // No Models Have been added
  if (filename == "")
    return false;

  std::stringstream ss;
  ss << pair_width_ << "_" << dipole_width_ << "_" << voxel_size_ << ".hash";
  filename += ss.str();
  return true;
}

main.cpp

int main() 
{
    ModelLibraryG4PCS d;
    if (!d.loadHashTable()) {
        /* Some Code to Construct a new Hash Table */
        d.saveHashTable();
    }
}
Was it helpful?

Solution

Your sample code isn't self-contained so I can only glance over it.

For now:

for(int i = 0; i < h.total_num_of_voxels_; ++i)
    ar & h.voxels_[i];
ar & h.num_of_voxels_;
ar & h.total_num_of_voxels_i_;

How would you think this could work? Clearly, h.total_num_of_voxels is either zero or indeterminate at the time of the loop when deserializing. Assuming it is an array (or at least contiguously stored elements in memory), use the array adaptor:

ar & boost::serialization::make_array(h.voxels_, h.total_num_of_voxels_); 
ar & h.num_of_voxels_;

Here's a reverse engineered example making some guesses based on your original code: Live On Coliru

Output

g++ -std=c++11 -Os -pedantic main.cpp -lboost_system -lboost_serialization && ./a.out && tail *.hash
archive filenameonetwo42_4242_999.hash
22 serialization::archive 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top