String::reserve¶
Level: reference · for working programmers
One line: Ensures room for at least additional more bytes — the argument is a headroom, not a total.
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_exact— without the round-upString::try_reserve— reporting failure instead of abortingString::with_capacity— the same idea at constructionString::capacity— what this changes
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