std::string::reserve în C++

reserve rezervă memorie dinainte; capacity arată cât încape; shrink_to_fit eliberează surplusul.

Sintaxă
void reserve(std::size_t n);
std::size_t capacity() const noexcept;
void shrink_to_fit();  // C++11

Ce face std::string::reserve

Un șir are o lungime (size) și o capacitate (capacity): câți octeți încap în memoria deja alocată. Când adaugi peste capacitate, șirul alocă o zonă mai mare și copiază textul acolo.

reserve(n) alocă dinainte loc pentru cel puțin n caractere, ca adăugările ulterioare să nu realoce. Nu schimbă conținutul sau lungimea. shrink_to_fit() cere eliberarea memoriei nefolosite (cererea poate fi ignorată).

Valorile exacte ale capacității depind de biblioteca standard. Exemplele de aici rulează cu libc++ (clang), unde un șir scurt (până la 22 de caractere) stă direct în obiect, fără alocare („small string optimization”).

Parametri

Parametru Descriere
n Numărul minim de caractere pentru care se rezervă memorie.

Ce returnează

capacity() returnează capacitatea curentă; celelalte nu returnează nimic.

Exemple

Exemplul 1: Lungime și capacitate

#include <iostream>
#include <string>

int main() {
    std::string s;
    std::cout << "gol: size " << s.size() << ", capacity " << s.capacity() << '\n';
    s.reserve(100);
    std::cout << "după reserve(100): size " << s.size() << ", capacity " << s.capacity() << '\n';
    s = "scurt";
    s.shrink_to_fit();
    std::cout << "după shrink_to_fit: size " << s.size() << ", capacity " << s.capacity() << '\n';
}

Rezultat

gol: size 0, capacity 22
după reserve(100): size 0, capacity 103
după shrink_to_fit: size 5, capacity 22

Exemplul 2: Câte realocări economisește reserve

#include <iostream>
#include <string>

int numara_realocari(bool cu_reserve) {
    std::string s;
    if (cu_reserve) s.reserve(10'000);
    int realocari = 0;
    std::size_t cap = s.capacity();
    for (int i = 0; i < 10'000; ++i) {
        s += 'x';
        if (s.capacity() != cap) {
            ++realocari;
            cap = s.capacity();
        }
    }
    return realocari;
}

int main() {
    std::cout << "Fără reserve: " << numara_realocari(false) << " realocări\n";
    std::cout << "Cu reserve: " << numara_realocari(true) << " realocări\n";
}

Rezultat

Fără reserve: 9 realocări
Cu reserve: 0 realocări

Greșeli frecvente

  • Crezi că reserve(10) face șirul de lungime 10 și scrii apoi la s[5]: lungimea este tot 0, deci accesul este nedefinit. Pentru lungime folosești resize.
  • Te bazezi pe valori exacte ale capacității: diferă între libc++, libstdc++ și MSVC.

Comenzi înrudite

  • std::string::resize: Schimbă lungimea șirului: îl taie la n caractere sau îl completează cu un caracter.
  • std::string::size: Returnează lungimea șirului în octeți; length() este exact același lucru.
  • std::string::append: Adaugă text la sfârșitul șirului, la fel ca +=, cu variante pentru bucăți și caractere repetate.