0

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
Eamon
  • 23
  • 6
  • Might help to include your model class – auburg Jun 10 '20 at 16:49
  • Yes, I edited the question to put the code in – Eamon Jun 10 '20 at 17:18
  • @Eamon Never using the boost serialization, I noticed this: `std::ofstream os(out_file_name);` -- you are opening the output file in text mode. You usually cannot use a text file generated on Mac (or Linux), and expect it to be successfully processed on a Windows machine if it is opened in text mode. The line-ending sequence is different between the two operating systems, EOF is different, etc. Maybe the error is due to lying to the serializer that it is a text file, when (on Windows) it isn't -- just a guess. – PaulMcKenzie Jun 10 '20 at 17:29
  • That is in check, I am on a PC running linux. Anyhow, the file I write is supposed to be read on the same machine – Eamon Jun 10 '20 at 17:34
  • Since the error is a thrown exception and not a seg fault, you could step into the boost code with a debugger to see why the exception is being thrown from boost (the code is not the simplest in the world, but simplicity isn't the goal right now). The cause could then be easily discovered. How to fix the issue could be a different story. – PaulMcKenzie Jun 11 '20 at 13:37

0 Answers0