writing directly to std::string internal buffers

I'm not sure the standard guarantees that the data in a std::string is stored as a char*. The most portable way I can think of is to use a std::vector, which is guaranteed to store its data in a continuous chunk of memory:

std::vector<char> buffer(100);
FunctionInDLL(&buffer[0], buffer.size());
std::string stringToFillIn(&buffer[0]);

This will of course require the data to be copied twice, which is a bit inefficient.


Update (2021): C++11 cleared this up and the concerns expressed here are no longer relevant.

After a lot more reading and digging around I've discovered that string::c_str and string::data could legitimately return a pointer to a buffer that has nothing to do with how the string itself is stored. It's possible that the string is stored in segments for example. Writing to these buffers has an undefined effect on the contents of the string.

Additionally, string::operator[] should not be used to get a pointer to a sequence of characters - it should only be used for single characters. This is because pointer/array equivalence does not hold with string.

What is very dangerous about this is that it can work on some implementations but then suddenly break for no apparent reason at some future date.

Therefore the only safe way to do this, as others have said, is to avoid any attempt to directly write into the string buffer and use a vector, pass a pointer to the first element and then assign the string from the vector on return from the dll function.


In C++98 you should not alter the buffers returned by string::c_str() and string::data(). Also, as explained in the other answers, you should not use the string::operator[] to get a pointer to a sequence of characters - it should only be used for single characters.

Starting with C++11 the strings use contiguous memory, so you could use &string[0] to access the internal buffer.


As long as C++11 gives contiguous memory guaranties, in production practice this 'hacky' method is very popular:

std::string stringToFillIn(100, 0);
FunctionInDLL(stringToFillIn.data(), stringToFillIn.size());