stl/string memory buffer copying

Started by
4 comments, last by Zahlman 15 years, 10 months ago
I'm using boost.serialization to send some data over a socket. I believe I can only serialize to fstream or to stringstream (the only two classes that inherit iostream) so I chose stringstream as my memory buffer. am i correct in this choice?

std::stringstream outbuffer(std::stringstream::out);
{
	boost::archive::text_oarchive outarchive(outbuffer);
	outarchive & frame; //serialize my data frame
}
So now I think I can send over my socket starting at outbuffer.str().c_str(), for length outbuffer.str().length(). I emulate this with a copy.
size_t outlength = outbuffer.str().length();
const std::string outstr = outbuffer.str();
const char* outraw = outbuffer.str().c_str();

std::vector<char> RecvBuffer;
RecvBuffer.resize(outlength); //edited

std::copy(outraw, outraw+outlength, RecvBuffer.begin());
i see the string contents are correct, but why can't i see the contents in the equivalent c_str? [Edited by - thedustbustr on June 12, 2008 10:45:00 AM]
Advertisement
const char* outraw = outbuffer.str().c_str();


outbuf is constructing a temporary std::string object which is reclaimed at the end of the str() call which leaves the character pointer obtained from c_str() dangling.


<oops - edit - ignore this i see you are resizing the buffer>
std::vector<char> RecvBuffer;std::copy(outraw, outraw+outlength, RecvBuffer.begin()); 


also this should probably be using an insertion iterator

std::copy(outraw, outraw+outlength, back_inserter( RecvBuffer));
hm. is this defined?

const std::string outstr = outbuffer.str();
const char* outraw = outstr().c_str();
copy
Quote:hm. is this defined?

const std::string outstr = outbuffer.str();
const char* outraw = outstr().c_str();
copy


looks fine

Quote:const char* outraw = outbuffer.str().c_str();


looks iffy to me
Quote:const std::string outstr = outbuffer.str();
const char* outraw = outstr().c_str();
copy


In this case the outbuffer returns a std::string which is constructed into outstr. the outstr then has a life for its scope and thus the pointer (outraw *) that is obtained from it will have the same useable scope. the str() call on the stringstream has to create this string object rather than return a reference to an internally held std::string because streambuf objects generally are not required to model their data contiguously - hence you can't get begin() and end() iterators only streaming iterators.

Quote:const char* outraw = outbuffer.str().c_str();


here the string returned from the str() method constructs a temporary which survives only for the scope of the expression. although you can obtain a char pointer from it using c_str(), once the statement has finished executing it is dangling. that it is a real object that will be a temporary and not a reference can also be seen from the return value types on the method in this doc

linky

Quote:stringstream::str public member function
string str ( ) const;
void str ( const string & s );
Get/set the associated string object

The first version returns a copy of the string object currently associated with the string stream buffer.
std::copy already knows how to copy out of a string, because it accepts iterators, and std::string knows how to provide iterators. Never minding anything about temporaries, it doesn't work to iterate a string with char*'s like that because the string doesn't guarantee its storage is contiguous. That's kind of part of why you're putting stuff in a vector buffer anyway, yeah? :)

const std::string outstr = outbuffer.str();std::vector<char> RecvBuffer(outstr.size()); // use the constructor to resizestd::copy(outstr.begin(), outstr.end(), RecvBuffer.begin());


Yep, really that simple. :)

This topic is closed to new replies.

Advertisement