You can safely assume that the memory buffer used by std::string is contiguous. Specifically, the address of the string’s first character can be used as the address for the whole string, just like a C-style char array:
1 | std::string str = "foo" ; |
2 | strncpy (&str[0], "bar" , 3); // str now contains "bar". |
Why is this safe? The current C++ standard apparently doesn’t guarantee that the string is stored contiguously, but it is in all known implementations. Additionally, the next C++ standard (C++0x) will make this guarantee. So the above usage is valid on all present and future C++ implementations.
Why is this important? It’s common for functions, especially in the Windows API, to “return” strings by copying them into a buffer passed to the function. Since the memory buffer used in std::string is contiguous you can safely pass it to the function, after resizing the string to the correct size.
A typical usage for Windows API functions:
01 | // get required buffer size |
03 | GetComputerNameA(NULL, &bufSize); |
04 | if (!bufSize && GetLastError() != ERROR_BUFFER_OVERFLOW) { |
05 | throw std::runtime_error( "GetComputerNameA failed" ); |
07 | // bufSize now contains required size of buffer, including null terminator |
08 | std::string buf(bufSize, '\0' ); |
09 | if (!GetComputerNameA(&buf[0], &bufSize)) { |
10 | throw std::runtime_error( "GetComputerNameA failed" ); |
12 | // bufSize now contains actual size of data |
14 | // now use buf as a regular std::string |
This is cumbersome but actually easier than plain C code, since you don’t have to manage the memory yourself.
Note that the expression &str[0] is valid only if str isn’t empty. Also, everything I’ve said also applies to std::wstring, the wide-character version of std::string.
References: