Boost logo

Boost :

From: Chuck Bear (chuck_at_[hidden])
Date: 2007-12-03 23:57:55


Thanks for your quick reply. Please allow me to apologize for not providing a full reproducer. (Wanted to get home for dinner.) Here it is (please ignore my general sloppiness with this but I'm still in a bit of a hurry):

#include <string>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>

#include <boost/serialization/export.hpp>

#include <sstream>
#include <stdio.h>

std::string defaultStringValue = "defaultValue";

class A
    friend class boost::serialization::access;
    std::string member;

    template<class Archive>
        void serialize(Archive & ar, const unsigned int serializer_version)
        ar & member;

    A() : member(defaultStringValue) {}

int main(int argc, char **argv)
    printf("%s\n", defaultStringValue.c_str());

    A start;
    start.member = "eefaultValue";

    std::ostringstream oss;
        const A &tmp = start;
        boost::archive::text_oarchive oar(oss);
        oar << tmp;
    std::string archString = oss.str();

    A end;
    std::istringstream iss(archString);
        boost::archive::text_iarchive ar(iss);
        ar >> end;

    printf("%s\n", defaultStringValue.c_str());
    return 0;

I have tried this on g++ 4.0.2 (RHEL4 update 3) and g++ 4.1.1. In both cases, it was 64-bit x86. The result is the same:
hp09:/home/cbear $ g++ -I/v3p/third-party/install/include -L/v3p/third-party/install/lib -lboost_serialization-gcc-mt-d str.cpp
hp09:/home/cbear $ ./a.out

Anyway, I hope this helps you (or others) with concern (a) below.

With regard to (b) below, I think you should proceed empirically. However I can't resist the temptation to speculate about the performance of, at least, the gcc implementation of std::string, in different implementations of a load() method:
1. I can't imagine that the temp std::string implementation would be a disaster, because of the character ref counting. It means you'd create the chars for the temp string, fill them in, and then transfer the reference over to the real string (without further adjustment of the characters). I do think that the reference counts are done with fancy atomic operations, so there is a bit of memory-synchronizing or bus locking going on here (in my patch) that wasn't in the 1.34 implementation.
2. I have to imagine that the typical case is that load() is loading into an empty string. Also I suspect that "is a string empty" can be established very cheaply. So if my suggestion is too slow, you can do what I've outlined only if the string to be loaded was non-empty when passed in.

Anyway, that's my $.02. Thanks again for looking into this.


-----Original Message-----
From: boost-bounces_at_[hidden] on behalf of Robert Ramey
Sent: Mon 12/3/2007 8:47 PM
To: boost_at_[hidden]
Subject: Re: [boost] Input archive loads seem to corrupt sharedcharacterstd::strings
Hmmm, this is a very well thought out and clearly explained post.

And you know, we've been surprised by some problems with
gcc 4.1+ related to export, which depends on serialization of a
string which identifies the class. Hmmmmmmmmmmm.

And I can appreciate what a huge amount of effort you had
to expend to find this.

I would like to

a) see if someone can confirm this issue and its cause.
b) see if this is the best solution. Since this string serialization is
a very common operation, the method should be as fast as
possible (lol - which seems to be the exact reason we find
ourselves with this predicament). Somehow I think just pulling
/pushing the characters from/to the input/output directly to to the
string will be faster than creating a temporary string.
c) after a/b above, it can be decided which version of boost
the fix should be rolled into.

Robert Ramey

Boost list run by bdawes at, gregod at, cpdaniel at, john at