1

How do I completely overwrite a std::string correctly? Is this correct?

std::string s = "Hello";
std::cout << s << std::endl;
s = "World";
std::cout << s << std::endl;

It works on my device, but it is defined behaviour to overwrite a std::string like this?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
RedBox
  • 133
  • 9
  • It's perfectly valid. `std::string` has an assignment operator that takes care of what is needed for `s = "World";` to be valid. – wohlstad Jun 13 '22 at 16:35
  • I.e. deallocate the previous data, and assign `s` with the new. – wohlstad Jun 13 '22 at 16:36
  • [operator= #3 overload](https://en.cppreference.com/w/cpp/string/basic_string/operator%3D): *Replaces the contents with those of null-terminated character string pointed to by s* – TheScore Jun 13 '22 at 16:41
  • If perfectly simple assignments invoked undefined behaviour no-one would be using `std::string`. It seems some beginners can't quite believe how simple the standard library is, they look for complications that don't exist. But, in any case, asking the question is a good sign. – john Jun 13 '22 at 17:00
  • @john It's a very good sign. I'm not sure I'd call the standard library "simple". It's got more footguns than the average NRA convention. Just spend two minutes on the Google search results page for `vector`, for starters. This level of caution is warranted, in my mind, especially when starting out. – Silvio Mayolo Jun 13 '22 at 17:13

1 Answers1

3

std::basic_string (the type from which std::string is a specialization) always stores its own data. So when you write

std::string s = "Hello";

You're invoking Constructor (5) of the available constructors (emphasis mine)

constexpr basic_string( const CharT* s,
                        const Allocator& alloc = Allocator() );

...

Constructs the string with the contents initialized with a copy of the null-terminated character string pointed to by s. The length of the string is determined by the first null character.

Then when you write

s = "World";

You're invoking overload (3) of the assignment operators (emphasis mine)

constexpr basic_string& operator=( const CharT* s );

...

Replaces the contents with those of null-terminated character string pointed to by s as if by assign(s, Traits::length(s))

So std::string keeps an internal buffer separate from the two literal character arrays you've written in your code, and that internal buffer knows how to manage its resources when you overwrite or move the string value.

See also Rule of Three (well, Rule of Five since C++11) for tons of good information on how to manage resources in your own classes in the same way.

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116