Skip to content

String::reserve

String methods · Strings

Level: reference · for working programmers

One line: Ensures room for at least additional more bytes — the argument is a headroom, not a total.

pub fn reserve(&mut self, additional: usize)

Stable since 1.0.0.

s.reserve(10) guarantees capacity() >= len() + 10. Reading it as "make the capacity 10" is the standard misunderstanding, and it under-reserves silently.

It may allocate more than asked, because it uses the same amortized-growth policy as pushing — that is deliberate, and it is what keeps a reserve-then-push loop from reallocating on every iteration. reserve_exact is the one that does not round up.

If the capacity is already sufficient, it does nothing.

It aborts on allocation failure. try_reserve returns a Result instead, which matters when the size comes from untrusted input.

Example

string_reserve.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let mut s = String::from("hello");
    println!("len {} capacity {}", s.len(), s.capacity());

    // Headroom, not a total: 10 MORE than the current length.
    s.reserve(10);
    println!("after reserve(10): len {} capacity {} (>= {})",
             s.len(), s.capacity(), s.len() + 10);

    // Already big enough: nothing happens.
    let before = s.capacity();
    s.reserve(1);
    println!("unchanged: {}", s.capacity() == before);

    // It may round up; reserve_exact does not.
    let mut a = String::from("ab");
    let mut b = String::from("ab");
    a.reserve(5);
    b.reserve_exact(5);
    println!("reserve {} / reserve_exact {}", a.capacity(), b.capacity());

    // The pattern it is for: size once, then push without reallocating.
    let mut out = String::new();
    out.reserve(32);
    let cap = out.capacity();
    for i in 0..8 { out.push_str(&format!("{i} ")); }
    println!("capacity unchanged through the loop: {}", out.capacity() == cap);
}

Verified output of string_reserve.rs — regenerated by tools/run_examples.py, never hand-typed.

len 5 capacity 5
after reserve(10): len 5 capacity 15 (>= 15)
unchanged: true
reserve 8 / reserve_exact 7
capacity unchanged through the loop: true

See also

String::reserve in the standard library ↗

Po polsku

Argument tej metody to zapas ponad obecną długość, a nie docelowa pojemność: s.reserve(10) gwarantuje capacity() >= len() + 10, więc dla pięcioliterowego "hello" wychodzi capacity 15, a nie 10. Odczytanie tego jako „ustaw pojemność na 10” jest najczęstszym nieporozumieniem i rezerwuje po cichu za mało — nic się nie wysypie, bufor po prostu dorośnie później sam. Wolno jej też przydzielić więcej, niż poproszono (w przykładzie reserve 8 tam, gdzie starczyłoby 7), i jest to zamierzone: ta sama polityka zamortyzowanego wzrostu co przy dokładaniu tekstu sprawia, że pętla „zarezerwuj, potem dopisuj” nie realokuje w każdym obrocie — a gdy nadmiaru nie chcesz, od tego jest reserve_exact. Na koniec rzecz, o której łatwo zapomnieć: przy braku pamięci reserve przerywa proces (abort), zamiast panikować, więc jeśli rozmiar pochodzi z niezaufanego wejścia, właściwe jest try_reserve zwracające Result.

Szukaj po polsku: rezerwowanie pojemności · zapas ponad długość · zamortyzowany wzrost bufora · rust String reserve capacity · rust try_reserve allocation failure