Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does the memory used for a string go when the string variable is re-assigned a new value?

Tags:

c++

memory

Say I have this simple function

void foo(string a, string b) {

  std::string a_string = a + a; 
  // reassign a new string to a_string
  a_string = b + b + b;

  // more stuff
}

Does the memory reserved for a+a get released as soon as a_string is assigned a new string?

Newbie in C++ memory management. I'm still wrapping my head around it.

like image 504
Curious Learner Avatar asked Sep 13 '25 08:09

Curious Learner


2 Answers

It depends if it is a short or long string:

std::string a_string = a + a;
// reassign a new string to a_string
a_string = b + b + b; 

First, a+a is constructed directly as a_string due to guaranteed copy elison (c++17). No freeing is going on here.

Then, if a_string is short enough it is allocated on stack, without additional heap allocations. This Short String Optimization (SSO) is performed by most compilers, but is not mandated by the standard.

If SSO took place, then this does not free any space in a_string but merely reuses it. The memory goes nowhere:

a_string = b + b + b; 

However, if a_string is too long for SSO, then this line does free heap space allocated for the string.

It is clear to see where memory goes when the declaration of std::string is examined:

template< 
   class CharT,
   class Traits = std::char_traits<CharT>,
   class Allocator = std::allocator<CharT>
> class basic_string;

The memory of the non-SSO string is allocated and freed with std::allocator. This allocator allocates and frees memory with the new and delete operaors. Usually they use malloc/free behind the scenes. This is how malloc and free work.

It is easy to find out how big as SSO string can be by running

std::cout << std::string().capacity() << '\n';

For clang 8.0.0 on 64 bit Intel SSO is for strings up to 22 chars, and for gcc 8.3 it is only 15 chars.

like image 175
Michael Veksler Avatar answered Sep 15 '25 22:09

Michael Veksler


From what I know the string is just copied to memory allocated for a_string since it is more efficient than freeing memory and allocating new one. If the memory allocated for (a+a) is less than size allocated for a_string it gets resized.

String manages the memory for you. You do not have to ever allocate buffer space when you add or remove data to the string. If you add more than will fit in the currently-allocated buffer, string will reallocate it for you behind the scenes.

std::string and its automatic memory resizing

like image 23
Nevus Avatar answered Sep 16 '25 00:09

Nevus