2

According to this answer, an internal buffer of std::string is not guaranteed to be contiguous under pre-C++11 standards. (Albeit almost all implementations use contiguous memory)

This means, technically, accessing a nth(n > 0?) element of a return value of string::data() or string::c_str() causes an undefined behavior. Is this correct?

std::string str = "Hello, World!"
str.c_str()[1]; // Which is equivalent to *(str.c_str() + 1), therefore UB?
suhdonghwi
  • 955
  • 1
  • 7
  • 20

2 Answers2

3

No, since the specification of C++98 clearly states what you get: An contiguous array of characters.

The internal implementation of the string storage is not necessarily reflected in method results. If the string is not stored in one part, the methods have to make sure, that you get what you want. This could mean, that the whole content is copied in a different place.

That is the reason, why you should not alter the string representation you get.

You and the person implementing the methods must both read carefully the standard describing what you get.

Juergen
  • 12,378
  • 7
  • 39
  • 55
0

str.c_str()[...]; is fine, so long as you don't run off the end of the string. After all, it's a C string so what else would you expect?

As for str.data(), cppreference has this to say:

const CharT* data() const returns a pointer to the underlying array serving as character storage. The pointer is such that the range [data(); data() + size()) is valid and the values in it correspond to the values stored in the string.

Now I don't know if this is entirely trustworthy, but cppreference does not qualify that statement as applying to any particular version of the standard. But, probably, it should do.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • The C++98 standard said *"a pointer to the initial element of an array whose first `size()` elements equal the corresponding elements of the string"*. So could *theoretically* be a separate buffer. But it never was, so the C++11 change was just documenting existing practice. – Bo Persson Jun 03 '18 at 10:45
  • @BoPersson Right, thanks. Makes sense. So what cppreference has to say can be relied on then, even before C++11. – Paul Sanders Jun 03 '18 at 10:59