0

Using the std::string class in C++, it is possible to modify a character using the array notation, like:

std::string s = "Hello"; s[0] = 'X'; cout << s << '\n'; 

I have checked that this code compiles, and prints "Xello" as expected. However, I was wondering what the cost of this operation is: is it constant time, or is it O(n) because the string is copied?

5
  • It is constant, you are modifying the buffer directly. Actually copying whole string under cx11 should be O(n) as it uses move semantics. Commented Jan 13, 2014 at 8:27
  • in C++11, s has its copy of the string from the moment it is constructed. C++03 allows copy on write, so it depends on the implementation. Commented Jan 13, 2014 at 8:28
  • There is no copying involved with this code whatsoever. We only have an initialization and an assignment. Commented Jan 13, 2014 at 9:02
  • I asked because if I wanted to do the same thing in Java, since strings are immutable, the only way would be to copy the string in O(n) time with the required change, iirc. Commented Jan 13, 2014 at 9:38
  • @H2CO3 the individual chars of "Hello" are always copied at some point in this code, in any version of C++. Commented Jan 13, 2014 at 9:39

3 Answers 3

1

The string isn't copied. The internal data is directly modified.

It basically gets the internal data pointer of the actual string memory, and modifies it. Imagine doing this:

char *data = &str[0]; for(size_t i = 0; i < str.size(); ++i) { data[i] = '!'; } 

The code sets every character of the string to an exclamation mark. But if the string was copied, then after the first write, the data pointer would become invalid.

Or to use another example: std::cout << str[5] << std::endl;

That prints the 6th character of the string. Why would that copy the string? C++ can't tell the difference between char c = str[5] and str[5] = c (except as far as const vs non-const function calls go).

Also, str[n] is guaranteed to never throw exceptions, as long as n < str.size(). It can't make that guarantee if it had to allocate memory internally for a copy - because the allocation could fail and throw.

(As @juanchopanza mentioned, older C++ standards permitted CoW strings, but the latest C++ standard forbids this)

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

1 Comment

This should be the selected answer because it provides an example and evidence.
0

You can modify stl string like in you example, no copy will be done. Standard library string class does not manage string pool like other languages do for strings (like Java). This operation is constant in complexity.

Comments

0

You do only modify the first element s[0], therefore it can't be O(n). You don't copy the string.

1 Comment

Faulty logic. On a COW implementation (now disallowed), changing a single element causes Copy On Write (by definition), and that copy definitely is O(n).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.