Boost logo

Boost Users :

From: 041021042_at_[hidden]
Date: 2007-01-17 21:20:07


Dear all,
I have been experimenting with the boost serialization library. The
working environment is
Cygwin + gcc3.4.4 + boost_1_33. I creat the following program, the
data structure is about
electric circuits. The data is saved successfully, but the loadded
data is wrong, some
pointers in the Wire objects points to invalid address. While when I
compile and run it in
another machine (Linux + gcc4.1.1 + boost_1_33_1), it works properly.
I wonder if it is a
compiler compatibility problem or there is something wrong in my
program.

#ifndef CIRCUIT_H_
#define CIRCUIT_H_
#include <ostream>
#include <string>
#include <vector>
#include <boost/archive/xml_iarchive.hpp>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/nvp.hpp>

class Pin {
    std::string parent;
    int index;

    friend std::ostream& operator<< (std::ostream& os, const Pin& pin);
    friend class boost::serialization::access;
    template<class Archive> void serialize(Archive & ar, const
unsigned int version) {
        ar & BOOST_SERIALIZATION_NVP(parent) & BOOST_SERIALIZATION_NVP
(index);
    }
public:
    Pin(std::string p="", int i=0) : parent(p), index(i) {}
};

class Wire {
    Pin* source;
    Pin* sink;

    friend std::ostream& operator<< (std::ostream& os, const Wire&
wire);
    friend class boost::serialization::access;
    template<class Archive> void serialize(Archive & ar, const
unsigned int version)
        { ar & BOOST_SERIALIZATION_NVP(source) &
BOOST_SERIALIZATION_NVP(sink);
    }
public:
    Wire(Pin* src=0, Pin* snk=0) : source(src), sink(snk) {}
};

class Block {
protected:
    std::string name;
    std::vector<Pin*> pins;

    Block() {}
    virtual std::ostream& print(std::ostream& os) const;
    friend std::ostream& operator<< (std::ostream& os, const Block&
blk);
    friend class boost::serialization::access;
    template<class Archive> void serialize(Archive & ar, const
unsigned int version ) {
        ar & BOOST_SERIALIZATION_NVP(name) & BOOST_SERIALIZATION_NVP
(pins);
    }
public:
    Block(std::string n, int np) : name(n), pins(np)
        { for (int i=0; i<np; i++) pins[i] = new Pin(n, i); }
    virtual ~Block() { for (int i=0; i<pins.size(); i++) delete pins
[i]; }
    
    Pin* get_pin(int i) { return pins[i]; }
    std::string get_name() { return name; }
    virtual std::ostream& print_recursive(std::ostream& os) const {
return print(os); }
};

class Circuit : public Block {
protected:
    std::vector<Block*> children;
    std::vector<Wire*> wires;
    std::ostream& print(std::ostream& os) const;
    friend class boost::serialization::access;
    template<class Archive> void serialize(Archive & ar, const
unsigned int version)
    {
        ar.register_type(static_cast<Circuit *>(NULL));
        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Block);
        ar & BOOST_SERIALIZATION_NVP(children) &
BOOST_SERIALIZATION_NVP(wires);
    }
public:
    Circuit() : Block() {}
    Circuit(std::string name, int np) : Block(name, np) { }
    void add_block(Block& b)
        { children.push_back(&b); }
    void add_wire(Wire& w)
        { wires.push_back(&w); }
    std::ostream& print_recursive(std::ostream& os) const;
};

std::ostream& operator<< (std::ostream& os, const Pin& pin);
std::ostream& operator<< (std::ostream& os, const Wire& wire);
std::ostream& operator<< (std::ostream& os, const Block& blk);
#endif /*CIRCUIT_H_*/

// main.cpp
#include <iostream>
#include <fstream>
#include "circuit.h"

void save_circuit(const Circuit& c, const char * filename)
{
    std::ofstream ofs(filename);
    boost::archive::xml_oarchive oa(ofs);
    oa << BOOST_SERIALIZATION_NVP(c);
}

void load_circuit(Circuit& c, const char * filename)
{
    std::ifstream ifs(filename);
    boost::archive::xml_iarchive ia(ifs);
    ia >> BOOST_SERIALIZATION_NVP(c);
}

int main()
{
    Circuit pe1("pe1",5);
    
    Circuit top("top", 4);
    top.add_block(pe1);
    Wire w6(top.get_pin(0), pe1.get_pin(0));
    Wire w7(top.get_pin(1), pe1.get_pin(1));
    Wire w8(pe1.get_pin(4), top.get_pin(2));
    
    top.add_wire(w6);
    top.add_wire(w7);
    top.add_wire(w8);
    
    top.print_recursive(std::cout);
    
    save_circuit(top, "circuit.xml");
    Circuit top2;
    load_circuit(top2, "circuit.xml");
    top2.print_recursive(std::cout);
}

There is another problem, when I inlined the 'save' and 'load'
function, the following error
occured, and the data couldn't be saved.
terminate called after throwing an instance
of 'boost::archive::xml_archive_exception'
  what(): unrecognized XML syntax
Aborted

The program is listed here:

int main()
{
// ... ...
// prepare data

    std::ofstream ofs("circuit.xml");
    boost::archive::xml_oarchive oa(ofs);
    oa << BOOST_SERIALIZATION_NVP(top);

    Circuit top2;
    std::ifstream ifs("circuit.xml");
    boost::archive::xml_iarchive ia(ifs);
    ia >> BOOST_SERIALIZATION_NVP(top2);
 
    top2.print_recursive(std::cout);
}

The error occured on both machine. Could anyone explain what's the
difference between the
two programs.

Best regards,
Roger Zhou


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net