Does "&s[0]" point to contiguous characters in a std::string?
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?
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)
ifpos < size()
, otherwise a reference to an object of typeT
with valuecharT()
; the referenced value shall not be modified
Continuing on, data()
is defined as:
Returns: A pointer
p
such thatp + i == &operator[](i)
for eachi
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.
Technically, no, since std::string
is not required to store its contents contiguously in memory.
However, in almost all implementations (every implementation of which I am aware), the contents are stored contiguously and this would "work."