Boost Binary Serialization Problem

11,605

Well, for one thing .data() doesn't have a terminal \0. It's not a c-string. I didn't even realize stringstream had a char* constructor (who in their right mind uses them anymore?) but apparently it does and I'd bet it expects \0.

Why are you trying to do it that way anyway? You're much better off working in C++ strings. Initialize is with os.str().

Edit: binary data contains lots of \0 characters and the std::string(char*) constructor stops at the first one. Your deserialization routine will then inevitably try to read past the end of the stream (because it isn't complete). Use the iterator constructor for std::string when you pass buf into the stringstream.

std::stringstream is(std::string(buf, buf+os.str().length()), flags);
Share:
11,605
user364688
Author by

user364688

Updated on June 27, 2022

Comments

  • user364688
    user364688 almost 2 years

    I have a problem using boost serialization using binary archives. It works when using a file stream but I want to store it in my local variable and ultimately save/load it to/from berkeley db. When executing the program I get a boost::archive::archive_exception: 'stream error' when instantiating the binary_iarchive.

    #include <sys/time.h>
    #include <string>
    #include <boost/serialization/serialization.hpp>
    #include <boost/archive/binary_oarchive.hpp>
    #include <boost/archive/binary_iarchive.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <fstream>
    #include <sstream>
    
    namespace boost {
    namespace serialization {
    
    template<class Archive>
    void serialize(Archive & ar, timeval & t, const unsigned int version)
    {
        ar & t.tv_sec;
        ar & t.tv_usec;
    }
    
    }//namespace serialization
    }//namespace boost
    
    
    int main(int, char**)
    {
        timeval t1;
        gettimeofday(&t1, NULL);
        char buf[256];
    
        std::stringstream os(std::ios_base::binary| std::ios_base::out| std::ios_base::in);
        {
            boost::archive::binary_oarchive oa(os, boost::archive::no_header);
            oa << t1;
        }
    
        memcpy(buf, os.str().data(), os.str().length());
        if(memcmp(buf, os.str().data(), os.str().length()) != 0)
            printf("memcpy error\n");
    
        timeval t2;
        {
            std::stringstream is(buf, std::ios_base::binary| std::ios_base::out| std::ios_base::in);
    
            boost::archive::binary_iarchive ia(is, boost::archive::no_header);
            ia >> t2;
        }
    
        printf("Old(%d.%d) vs New(%d.%d)\n", t1.tv_sec, t1.tv_usec, t2.tv_sec, t2.tv_usec);
    
        return 0;
    }
    

    It works when initializing is with os.str(), so I guess my way of copying the data to my buffer or to is is wrong.