2

Why C++ empty string can be accessed at any position without error?

For example,

string str(""); 

str[1], str[2] will just return empty.

Why doesn't the following statement throw error?

str[2] = 'a'

But, printing out str still show empty string.

I am confused here and probably miss something.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
day
  • 1,047
  • 3
  • 11
  • 20
  • what compiler are you using? because mine explodes when i try to assign `std::string str("")` `str[2] = 'a'` – Ediac Jul 01 '15 at 15:59
  • It could return empty, but it could also format your hard drive. – Don Reba Jul 01 '15 at 16:11
  • 1
    All you're missing is that this is _Undefined Behaviour_, that C++ doesn't protect you from _Undefined Behaviour_, and that it's generally better to avoid UB instead of trying to guess which particular unpredictable failure mechanism a given compiler will select. – Useless Jul 01 '15 at 16:13
  • Thanks a lot. Very useful answers. – day Jul 01 '15 at 17:58

4 Answers4

4

Accessing out-of-range subscript is undefined. For an empty std::string, using any subscript is illegal.

However, it's not required for the library to check the value of the subscript. The job of making sure the subscript is legal is left to the programmer, i.e, you.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
3

The string is (sort of) an array of characters you can stick stuff in. When you make it "" it guarantees a length of at least 0 characters are available. When you assign something to character [2] the behaviour is undefined and it is entitled to blow up, but there's a fair chance it will be large enough to absorb your mistake without noticing...

Andy Newman
  • 1,178
  • 2
  • 8
  • 23
  • And a very good chance that if it does blow up, it will do so somewhere completely unexpected and apparently not connected to the string at all. – Charlie Martin Jul 01 '15 at 16:15
3

std::string elements can be accessed using the [] operator and using the at() function. The operator is required to perform no bounds checks, just like regular array access in C++, whereas the function throws out_of_range for invalid indices.

Don Reba
  • 13,814
  • 3
  • 48
  • 61
2

In addition to the answers by Yu and Andy, which are correct of course, I'd like to point you to string::at which, unlike string::operator[] would do bounds checking and through an exception if you attempt out-of-bounds access:

#include <string>
int main()
{
    std::string s("");
    return s.at(1);
}

The output:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at
Aborted (core dumped)
Michael
  • 5,775
  • 2
  • 34
  • 53