Jump to content
  • Advertisement
Sign in to follow this  
thedustbustr

stl/string memory buffer copying

This topic is 3813 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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));

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 resize

std::copy(outstr.begin(), outstr.end(), RecvBuffer.begin());


Yep, really that simple. :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!