Eamon
Eamon

Reputation: 23

runtime issue with boost serialization using different compilers/environments

I have a piece of code that serializes a struct on file.

int main(int argn, char* argv[]){
    if (argn > 2){
        std::cout << "Error! this program requires a single argument.\n";
        return 1;
    }
    std::string model_filename{argv[1]};
    std::string out_f = model_filename.replace(model_filename.length()-4,4,".dat");
    std::string out_file_name{out_f};
    std::ifstream is(argv[1]);
    std::string line;
    model m;
    while (std::getline(is,line))
    {// build m from input file
    }

    std::ofstream os(out_file_name);
    boost::archive::text_oarchive oa(os);
    oa << m ;
    os.close();

Now from a different program on the same computer I read the serialized object

int main(int argc, char* argv[]){
    const double stdev{0.03};

    std::string model_filename{argv[1]};
    std::ifstream is(model_filename);
    boost::archive::text_iarchive ia(is); **// <== throw exception on this line!!!**
    model m; 
    ia >> m; 
    ...

This code run as expected on my macbook (clang compiler) but it actually crashes on a pc (gcc 7.5). I build the codes with the same cmake script on both cases. The exception thrown is

terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  input stream error

Process finished with exit code 134 (interrupted by signal 6: SIGABRT)

I just wonder what the problem might be (and what the solution looks like!) Any suggestion?

EDIT: to answer the comment about the class I define a Parameter class


    class Parameter {
        paramType type;
        bool active{true};
        double value;
        friend boost::serialization::access;

        template<typename Archive>
        void serialize(Archive &ar, const unsigned int version) {
            ar & type;
            ar & active;
            ar & value;
        }

    public:
        Parameter() = default;

        Parameter(paramType type, bool isActive, double value) : type(type), active(isActive), value(value) {}

        paramType getType() const {
            return type;
        }

        bool isActive() const {
            return active;
        }

        double getValue() const {
            return value;
        }

        void setType(paramType _type) {
            Parameter::type = _type;
        }

        void setIsActive(bool isActive) {
            Parameter::active = isActive;
        }

        void setValue(double _value) {
            Parameter::value = _value;
        }

        friend std::ostream &operator<<(std::ostream &os, const Parameter &parameter) {
            os << "type: " << parameter.type << " active: " << parameter.active << " value: " << parameter.value;
            return os;
        }
    };

a set of parameters make a node


    struct node {
        std::map<int, Parameter> params;
    public:
        node() = default;

    private:
        friend boost::serialization::access;

        template<typename Archive>
        void serialize(Archive &ar, const unsigned int version) {
            ar & params;
        }

    };

and a std::vector of nodes makes the model


    struct model {
        model() = default;
// fields ::
        std::vector<node> nodes;

    private:
        friend boost::serialization::access;

        template<typename Archive>
        void serialize(Archive &ar, const unsigned int version) {
            ar & nodes;
        }
    };

and to be complete, here is the include section of the model header

#include <iostream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <map>
#include <boost/serialization/map.hpp>
#include <vector>
#include <boost/serialization/vector.hpp>
#include <boost/random.hpp>
#include <fstream>
#include <cmath>
#include <numeric>
#include <exception>
#include <algorithm>
#include <boost/histogram.hpp>
#include <boost/timer/timer.hpp>
#ifdef _OMP
#include <omp.h>
#endif

Upvotes: 0

Views: 78

Answers (0)

Related Questions