Reputation: 5892
If I have the following code:
std::string hello = "hello world";
char* internalBuffer = &hello[0];
Is it then safe to write to internalBuffer up to hello.length()? Or is this UB/implemention defined? Obviously I can write tests and see that this works, but it doesn't answer my question.
Upvotes: 2
Views: 105
Reputation: 4847
Yes, it's safe. No, it's not explicitly allowed by the standard.
According to my copy of the standard draft from like half a year ago, they do assure that data()
points at a contiguous array, and that that array be the same as what you receive from operator[]:
21.4.7.1 basic_string accessors [string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
From this one can conclude that operator[] returns a reference to some place within that contiguous array. They also allow the returned reference from (non-const) operator[] be modified.
Having a non-const reference to one member of an array I dare to say that we can modify the entire array.
Upvotes: 2
Reputation: 2371
In practice it is safe, theoretically - no.
C++ standard doesn't force to implement string
as a sequential character array like it does for the vector
. I'm not aware of any implementation of string
where it is not safe, but theoretically there is no guarantee.
http://herbsutter.com/2008/04/07/cringe-not-vectors-are-guaranteed-to-be-contiguous/
Upvotes: 0
Reputation: 54609
The relevant section in the standard is §21.4.5:
const_reference operator[](size_type pos) const noexcept;
reference operator[](size_type pos) noexcept;
[...]
Returns:
*(begin() + pos)
ifpos < size()
, otherwise a reference to an object of typeT
with valuecharT()
; the referenced value shall not be modified.
If I understand this correctly, it means that as long as the index given to operator[]
is smaller than the string's size
, one is allowed to modify the value. If however, the index is equal to size
and thus we obtain the \0
terminating the string, we must not write to this value.
Cppreference uses a slightly different wording here:
If pos == size(), a reference to the character with value
CharT()
(the null character) is returned. For the first (non-const) version,the behavior is undefined if this character is modified.
I read this such that 'this character' here only refers to the default constructed CharT
, and not to the reference returned in the other case. But I admit that the wording is a bit confusing here.
Upvotes: 0