7

Is there any rules in the standard that violates modifications of internal std::string buffer returned by operator[] like this:

void foo(char* buf)
{
  buf[1] = 's';
}

std::string str = "str";
modify_buffer(&str[0]);

I found the following quote in the C++11 draft about data and c_str functions:

Requires: The program shall not alter any of the values stored in the character array.

But I don't see any about operator[].

4
  • 3
    There is no std::string in your example. Commented Aug 10, 2016 at 14:03
  • 3
    Simply because data() and c_str() returns const char* Commented Aug 10, 2016 at 14:03
  • @aschepler Sorry, fixed Commented Aug 10, 2016 at 14:04
  • If you can modify the contents with operator[] then why do you think a pointer to the element would be any different? Commented Aug 10, 2016 at 14:11

1 Answer 1

11

operator[]

operator[] returns a reference to the character. So if the string is NOT const, you can modify it safely.

For C++ 11, the characters are stored contiguously, so you can take &str[0] as the beginning of the underlying array whose size is str.size(). And you can modify any element between [ &str[0], &str[0] + str.size() ), if the string is NOT const. e.g. you can pass &str[0] and str.size() to void func(char *arr, size_t arr_size): func(&str[0], str.size())

data() and c_str() members

For C++11 and C++14, both data() and c_str() returns const CharT*, so you CANNOT modify element with the returned pointer. However, from C++17, data() will return CharT*, if string is NOT const. And data() will be an alias to &str[0].

Sign up to request clarification or add additional context in comments.

5 Comments

I don't exactly know what C11++ says, but as C11++ is not the only standard about C++, I would not depend on consecutive array elements being stored consecutivelly. It's common, as allocating contiguous memory is in general expensive, to store char elements in buckets, so don't generally expect them all to be consecutive. I have written a String (beware that i don't write string) with same semantics as string but with copy on write specifications, and chars where contiguous up to some point only.
@for_stack, can you provide a reference in the spec for the claims in your paragraph that begins "For C++ 11"? This sounds like an authoritative claim; it would be nice to be able to see where it comes from. Thanks!
@bhaller Please check the second paragraph of this link
@for_stack, thanks! That seems to only make a statement about contiguous storage – your first claim. Is there also a guarantee regarding modification through the pointer being legal? I.e., a guarantee that std::string is not caching various attributes of the string data, or duplicating the data internally for some reason, or anything like that, such that not only reading but also writing through the pointer is legal? I imagine in practice it generally works, but I'm wondering whether there is a hard guarantee of that, in C++11 at least.
From the link: a pointer to s[0] can be passed to functions that expect a pointer to the first element of a CharT[] array. Since the function can modify the input char array, you can safely modify the string through the pointer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.