Prithivi Raj
Prithivi Raj

Reputation: 61

Why std::string object when constructed with default constructor behaves differently?

I tried the below program:

#include <iostream>
#include <string>

int main ()
{
  std::string str;
  str[0] = 'o';
  str[1] = 'k';
  std::cout << str.length();
  std::cout << "as a whole :";
  std::cout << str << std::endl;
  std::cout << "character by character :";
  std::cout << str[0] << str[1] << std::endl;      
  return 0;
}

I do not understand why I can not print the string as a whole using the object variable and why the length is returning as 0 since clearly I have added the characters using the subscript operator as that would return char reference so I know that is legal.

In addition, I did not get any kind of exception. So there is that. Obviously, there is a lot happening behind the scenes in the std::string class and I know I am missing something. Could someone help me with this?

Upvotes: 3

Views: 568

Answers (3)

JeJo
JeJo

Reputation: 32847

I don't understand why I can't print the string as a whole [...]...

Because you are experiencing the undefined behaviour.

This

std::string str;

construct a default string with 0 allocations of memory. Meaning modifying via std::string::operator[] will cause a asses out of bounds undefined behaviour. Therefore, anything could happen. In your case, the length returns 0.


[...] clearly I have added the characters using the subscript operator as that would return char reference so I know that is legal.

No, you have not, for the reason mentioned above. For the reference, the std::string::operator[]

Returns a reference to the character at specified location pos. No bounds checking is performed. If pos > size(), the behavior is undefined.


As possible fixes, you might want to std::string::resize before, accessing the elements.

#include <string>

std::string str;
str.resize(2);
str[0] = 'o';
str[1] = 'k';
// ... now it has defined behaviour

or std::string::push_back each charector into the string.

#include <string>

std::string str;
str.push_back('o');
str.push_back('k');
// ... now it has defined behaviour

Upvotes: 5

ikh
ikh

Reputation: 10417

You added nothing to the empty string str. Instead, you're trying to edit non-existing element of the empty string. Subscript operator of std::string does not add element automatically. (unlike std::map) Moreover, it is not guaranteed that subscript operator throws some exception. If you want safe-subscript-operation, You can use std::string::at function.

You can use += operator to append something to your string.

str += 'o';
str += 'k';

Upvotes: 3

Blaze
Blaze

Reputation: 16876

You have a string of length 0 and then you try to modify its contents using the subscript operator. That's undefined behavior, so at this point, no particular outcome is guaranteed. If you used at() instead, it would have exposed the mistake and thrown an exception instead.

why the length is returning as 0

It started out as 0 and you didn't do anything to add to it (such as push_back or +=). But then again, since what you did earlier was undefined behavior, anything could have happened here.

In addition, I didn't get any kind of exception.

You can try std::string::at instead, which will throw an std::out_of_range exception when you try that.

Upvotes: 5

Related Questions