Does "&s[0]" point to contiguous characters in a std::string?

c++, c++03, memcpy, stdstring

Solution

A std::string's allocation is not guaranteed to be contiguous under the C++98/03 standard, but C++11 forces it to be. In practice, neither I nor Herb Sutter know of an implementation that does not use contiguous storage.

Notice that the `&s[0]` thing is always guaranteed to work by the C++11 standard, even in the 0-length string case. It would not be guaranteed if you did `str.begin()` or `&*str.begin()`, but for `&s[0]` the standard defines `operator[]` as:

Returns: `*(begin() + pos)` if `pos < size()`, otherwise a reference to an object of type `T` with value `charT()`; the referenced value shall not be modified

Continuing on, `data()` is defined as:

Returns: A pointer `p` such that `p + i == &operator[](i)` for each `i` in `[0,size()]`.

(notice the square brackets at both ends of the range)

Notice: pre-standardization C++0x did not guarantee `&s[0]` to work with zero-length strings (actually, it was explicitly undefined behavior), and an older revision of this answer explained this; this has been fixed in later standard drafts, so the answer has been updated accordingly.

Problem

I'm doing some maintenance work and ran across something like the following: ``` std::string s; s.resize( strLength ); // strLength is a size_t with the length of a C string in it. memcpy( &s[0], str, strLength ); ``` I know using &s[0] would be safe if it was a std::vector, but is this a safe use of std::string?

Original source