Home > OS >  Why capacity of std::string is 15. Why my reserve() is ignored?
Why capacity of std::string is 15. Why my reserve() is ignored?

Time:11-18

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string s;
    s.reserve(5);
    cout << s.capacity() << endl;
}

The reserve is a std::string's function that sets the capacity. The capacity function shows the space size of c_string in the std::string.

But, the result is not 5, but 15. I don't know why.

CodePudding user response:

A quick search gives me : https://cplusplus.com/reference/string/string/reserve/

If n is greater than the current string capacity, the function causes the container to increase its capacity to n characters (or greater).

In all other cases, it is taken as a non-binding request to shrink the string capacity: the container implementation is free to optimize otherwise and leave the string with a capacity greater than n.

There is no guarantee that by calling reserve will leave you a capacity exactly as what you provided

CodePudding user response:

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.

  • Related