Note that also
int main()
{
std::string s;
std::cout << s.capacity() << "\n";
s.reserve(5);
std::cout << s.capacity() << "\n";
}
Would print 15
twice.
Consider the output of this
#include <iostream>
#include <string>
int main()
{
std::string s;
std::cout << s.capacity() << "\n";
std::cout << sizeof(std::string) << "\n";
std::cout << sizeof(char) << "\n";
std::cout << sizeof(char*) << "\n";
std::cout << sizeof(size_t) << "\n";
}
Possible output:
15
32
1
8
8
A std::string
somehow has to store the character array, its size, capacity and perhaps some more bookkeeping. The obvious way to store a character array is with a char*
and a size_t
for the size (only null-terminator is not sufficient for constant time size()
and others). However, thats 16 bytes. A single character is only 1 byte. Hence an empty std::string
before allocating any dynamic memory has enough space to store some characters by reusing memory that is used for other stuff once the string grows.
Thats is short string optimization. I only outlined the general idea. For details I refer you to other resources or the implementation.
Further reserve(n)
will only make sure that the string has enough space for at least n
characters. An empty string already has enough space to store 5 characters. When n
is smaller than the current capacity the string might shrink or not (it does not since C++20).
TL;DR: Your call to reserve
is not ignored. After the call the string has enough capacity to hold 5 characters. The initial capacity on your implementation seems to be 15. It could be some other value as well.