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
5
  • Might help to include your model class Commented Jun 10, 2020 at 16:49
  • Yes, I edited the question to put the code in Commented Jun 10, 2020 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. Commented Jun 10, 2020 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 Commented Jun 10, 2020 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. Commented Jun 11, 2020 at 13:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.