Vec::reserve¶
Level: reference · for working programmers
One line: Make room for additional more elements on top of the current length.
Stable since 1.0.0.
The argument is additional elements beyond len(), not a target capacity. v.reserve(10) on a vector of length 3 guarantees room for 13. Reading it as "make the capacity 10" is the standard mistake, and on a non-empty vector it under-reserves.
If there is already room it does nothing. Otherwise it reallocates once, and it is allowed to over-allocate deliberately — that speculative slack is what keeps repeated small reservations amortised rather than quadratic. reserve_exact is the version that does not.
Capacity is counted in elements, so reserve(10) on a Vec<u64> asks the allocator for 80 bytes.
You need it less often than it looks: extend_from_slice, collect and extend from an iterator with a known length all reserve once for the whole batch. The case that genuinely wants it is a loop of pushes whose count you can compute beforehand but which no single call can see.
Panics if the new capacity overflows usize or exceeds isize::MAX bytes. try_reserve returns Err instead.
Example¶
vec_reserve.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
// "additional" is on top of the CURRENT LENGTH, not the current capacity.
let mut v = vec![1, 2, 3];
v.reserve(10);
println!("len {} capacity at least 13: {}", v.len(), v.capacity() >= 13);
// If there is already room, it does nothing.
let mut v: Vec<u8> = Vec::with_capacity(100);
let before = v.capacity();
v.reserve(10);
println!("already had room, unchanged: {}", v.capacity() == before);
// It may over-allocate deliberately, so repeated small reserves stay
// amortised rather than reallocating every time.
let mut v: Vec<u32> = Vec::new();
v.reserve(1);
println!("reserve(1) on an empty Vec<u32> gave capacity {}", v.capacity());
// The usual use: you know the size just before you fill it.
let words = ["alpha", "beta", "gamma"];
let count = |reserve: bool| {
let mut out: Vec<char> = Vec::new();
if reserve { out.reserve(words.iter().map(|w| w.len()).sum()); }
let mut reallocs = 0;
for w in words {
for c in w.chars() {
let before = out.capacity();
out.push(c);
if out.capacity() != before { reallocs += 1; }
}
}
(out.len(), reallocs)
};
println!("with reserve: {:?} (len, reallocations)", count(true));
println!("without reserve: {:?}", count(false));
// extend() from an iterator with a known length already reserves for you,
// which is why this is rarely needed with collect() or extend_from_slice().
let mut v: Vec<u8> = Vec::new();
v.extend_from_slice(&[0; 50]);
println!("extend_from_slice reserved once: len {} cap {}", v.len(), v.capacity());
// Capacity is measured in ELEMENTS. Reserving 10 for a Vec<u64> asks the
// allocator for 80 bytes.
let mut v: Vec<u64> = Vec::new();
v.reserve(10);
println!("10 u64 slots = {} bytes of buffer", v.capacity() * size_of::<u64>());
}
Verified output of vec_reserve.rs — regenerated by tools/run_examples.py, never hand-typed.
len 3 capacity at least 13: true
already had room, unchanged: true
reserve(1) on an empty Vec<u32> gave capacity 4
with reserve: (14, 0) (len, reallocations)
without reserve: (14, 3)
extend_from_slice reserved once: len 50 cap 50
10 u64 slots = 80 bytes of buffer
See also¶
Vec::reserve_exact— the same, without the speculative slackVec::try_reserve— the same, returningResultVec::with_capacity— reserving before the vector existsVec::capacity— reading back what you got