Boost serialization: Problem reading strings from binary archive
Hello, I am having a strange problem with std::string as I am trying to read from a binary archive using Boost serialization. I am new to this, and it is possible that I have not understood the usage. In the code below, the string "faultblock" seems to be causing the problem. The code crashes in the ia & tst line which is reading back the archive - the stack indicates that it is trying to read an invalid string. I have tried to minimize the code I need to post, but sorry if this is still too much. I'd appreciate any help with this. I am using Boost 1.34.0 on windows XP. Best Regards Mahesh // // test.cpp // #include <iomanip> #include <iostream> #include <fstream> #include <string> #include <vector> #include <boost/archive/text_iarchive .hpp> #include <boost/archive/text_oarchive.hpp #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include "Attribute4dv.h" using namespace std; class Test { private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar.template register_type<AttrDouble4dv>(); ar.template register_type<AttrString4dv>(); ar & _attrs; } public: vector<Attribute4dv*> _attrs; Test() {} ~Test() {} }; int main(int argc, char* arv[]) { // save data to archive { Test* tst = new Test; vector<double> dVals; dVals.push_back(1.1); dVals.push_back(2.2); AttrDouble4dv* attr1 = new AttrDouble4dv; attr1->_name = "attr1"; attr1->_vals = dVals; tst->_attrs.push_back(attr1); vector<string> lut; lut.push_back("2001"); lut.push_back("2002"); vector<int> lutIndices; lutIndices.push_back (0); lutIndices.push_back(1); AttrString4dv* attr2 = new AttrString4dv; attr2->_name = "faultblock"; attr2->_indices = lutIndices; attr2->_lut = lut; tst->_attrs.push_back(attr2); const Test* tst2 = tst; std::ofstream ofs("test.bin"); boost::archive::binary_oarchive oa(ofs); oa & tst2; } // read data from archive { Test* tst; std::ifstream ifs("test.bin", std::ios::binary); boost::archive::binary_iarchive ia(ifs); ia & tst; int j = 0; } return 0; } // // Attribute4dv.h // #ifndef _ATTRIBUTE4DV_H #define _ATTRIBUTE4DV_H #include <vector> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> // Base class class Attribute4dv { public: Attribute4dv() {} virtual ~Attribute4dv() {} // name of attribute std::string _name; private: // for serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { ar & _name; } }; // double attributes class AttrDouble4dv : public Attribute4dv { public: AttrDouble4dv() {} ~AttrDouble4dv() {} std::vector<double> _vals; private: // for serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { // save/load base class info ar & boost::serialization::base_object<Attribute4dv>(*this); ar & _vals; } }; // string attributes class AttrString4dv : public Attribute4dv { public: AttrString4dv() {} ~AttrString4dv() {} // a lookup table (LUT) of strings std::vector<std::string> _lut; // indices to the LUT std::vector<int> _indices; private: // for serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { // save/load base class info ar & boost::serialization::base_object<Attribute4dv>(*this); ar & _lut; ar & _indices; } }; #endif // _ATTRIBUTE4DV_H
try replacing std::ofstream ofs("test.bin"); with std::ofstream ofs("test.bin", ios::binary); does that help? Robert Ramey "Mahesh Venkitachalam" <mkvenkit.vc@gmail.com> wrote in message news:6164abb70711100543x284a2592p2189dd14a54d0d54@mail.gmail.com... Hello, I am having a strange problem with std::string as I am trying to read from a binary archive using Boost serialization. I am new to this, and it is possible that I have not understood the usage. In the code below, the string "faultblock" seems to be causing the problem. The code crashes in the ia & tst line which is reading back the archive - the stack indicates that it is trying to read an invalid string. I have tried to minimize the code I need to post, but sorry if this is still too much. I'd appreciate any help with this. I am using Boost 1.34.0 on windows XP. Best Regards Mahesh // // test.cpp // #include <iomanip> #include <iostream> #include <fstream> #include <string> #include <vector> #include <boost/archive/text_iarchive .hpp> #include <boost/archive/text_oarchive.hpp #include <boost/archive/binary_oarchive.hpp> #include <boost/archive/binary_iarchive.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/utility.hpp> #include <boost/serialization/list.hpp> #include "Attribute4dv.h" using namespace std; class Test { private: friend class boost::serialization::access; template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar.template register_type<AttrDouble4dv>(); ar.template register_type<AttrString4dv>(); ar & _attrs; } public: vector<Attribute4dv*> _attrs; Test() {} ~Test() {} }; int main(int argc, char* arv[]) { // save data to archive { Test* tst = new Test; vector<double> dVals; dVals.push_back(1.1); dVals.push_back(2.2); AttrDouble4dv* attr1 = new AttrDouble4dv; attr1->_name = "attr1"; attr1->_vals = dVals; tst->_attrs.push_back(attr1); vector<string> lut; lut.push_back("2001"); lut.push_back("2002"); vector<int> lutIndices; lutIndices.push_back (0); lutIndices.push_back(1); AttrString4dv* attr2 = new AttrString4dv; attr2->_name = "faultblock"; attr2->_indices = lutIndices; attr2->_lut = lut; tst->_attrs.push_back(attr2); const Test* tst2 = tst; std::ofstream ofs("test.bin"); boost::archive::binary_oarchive oa(ofs); oa & tst2; } // read data from archive { Test* tst; std::ifstream ifs("test.bin", std::ios::binary); boost::archive::binary_iarchive ia(ifs); ia & tst; int j = 0; } return 0; } // // Attribute4dv.h // #ifndef _ATTRIBUTE4DV_H #define _ATTRIBUTE4DV_H #include <vector> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/string.hpp> #include <boost/serialization/vector.hpp> // Base class class Attribute4dv { public: Attribute4dv() {} virtual ~Attribute4dv() {} // name of attribute std::string _name; private: // for serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { ar & _name; } }; // double attributes class AttrDouble4dv : public Attribute4dv { public: AttrDouble4dv() {} ~AttrDouble4dv() {} std::vector<double> _vals; private: // for serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { // save/load base class info ar & boost::serialization::base_object<Attribute4dv>(*this); ar & _vals; } }; // string attributes class AttrString4dv : public Attribute4dv { public: AttrString4dv() {} ~AttrString4dv() {} // a lookup table (LUT) of strings std::vector<std::string> _lut; // indices to the LUT std::vector<int> _indices; private: // for serialization friend class boost::serialization::access; template<class Archive> void serialize(Archive &ar, const unsigned int version) { // save/load base class info ar & boost::serialization::base_object<Attribute4dv>(*this); ar & _lut; ar & _indices; } }; #endif // _ATTRIBUTE4DV_H ------------------------------------------------------------------------------ _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Yes, that was it - thanks very much for looking at it. I was using a text archive before, and everything was working even after I switched to binary, till I started using strings. I missed out on adding ios::binary to the write... Best Regards Mahesh On Nov 10, 2007 10:03 PM, Robert Ramey <ramey@rrsd.com> wrote:
try replacing std::ofstream ofs("test.bin"); with std::ofstream ofs("test.bin", ios::binary); does that help?
Robert Ramey
"Mahesh Venkitachalam" <mkvenkit.vc@gmail.com> wrote in message news:6164abb70711100543x284a2592p2189dd14a54d0d54@mail.gmail.com... Hello,
I am having a strange problem with std::string as I am trying to read from a binary archive using Boost serialization. I am new to this, and it is possible that I have not understood the usage. In the code below, the string "faultblock" seems to be causing the problem. The code crashes in the ia & tst line which is reading back the archive - the stack indicates that it is trying to read an invalid string.
...
participants (2)
-
Mahesh Venkitachalam
-
Robert Ramey