4

Sample below:

string s1 = "abcde";
string s2(s1, s1.size()); // s1.size() = 5.

Notice that s1.size() = 5 and the last allowable index = 4 (for character 'e'). The above runs fine returning empty string. Only when pos = 6 then it fail with exception out-of-range. Why?

According to cppereference site:

Exceptions
3) std::out_of_range if pos > other.size()

Shouldn't the correct exception be "if pos >= other.size()"?

cigien
  • 57,834
  • 11
  • 73
  • 112
yapkm01
  • 3,590
  • 7
  • 37
  • 62
  • 1
    `std::string` is now required to have a null terminator. – PaulMcKenzie Feb 07 '23 at 19:41
  • Hm since when? I thought if s is C character array then yes. – yapkm01 Feb 07 '23 at 19:42
  • 1
    [See this](https://stackoverflow.com/questions/6077189/will-stdstring-always-be-null-terminated-in-c11). But as the answer states, writing anything other than `0` in that position will more than likely mess up how the `std::string` will concatenate, remove, etc. – PaulMcKenzie Feb 07 '23 at 19:47
  • @yapkm01 Did any of the answers answer your question? – Ted Lyngmo Feb 14 '23 at 19:34

2 Answers2

8

Since C++11, s1[s1.size()] is required to work and will return a reference to the '\0' at the end of the string. Changing the '\0' to something else however leads to undefined behavior. You are however allowed to write '\0' there.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
1

Notice that s1.size() = 5 and the last allowable index = 4 (for character 'e').

This is wrong. Since C++11, the last allowable character index is size(), not size()-1. std::basic_string's data buffer is now required to be null terminated, and accessing index size() (even on an empty string) is required to return a reference to a valid '\0' character.

The above runs fine returning empty string.

As it should be.

Only when pos = 6 then it fail with exception out-of-range.

Correct, because that really is out of bounds.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770