reserve() and shrink_to_fit()
Vec<T> provides explicit capacity control methods—.reserve(), .reserve_exact(), .try_reserve(), .shrink_to(), .shrink_to_fit(), and .into_boxed_slice()—to pre-allocate space before bulk insertions or release unused heap memory after a vector reaches its final size.
Capacity Growth and Shrinking Reference
| Method | Parameter Meaning | Allocation Strategy |
|---|---|---|
v.reserve(additional) |
Space for additional more elements (target >= v.len() + additional) |
Geometric growth (at least doubles capacity to amortize future calls) |
v.reserve_exact(additional) |
Space for additional more elements (target >= v.len() + additional) |
Allocates the exact minimum for v.len() + additional |
v.try_reserve(additional) |
Same as reserve, but fallible |
Returns Result<(), TryReserveError> instead of panicking/aborting on OOM |
v.shrink_to(min_capacity) |
Target total capacity | Shrinks capacity down toward max(v.len(), min_capacity) |
v.shrink_to_fit() |
None | Shrinks capacity as close to v.len() as the allocator supports |
v.into_boxed_slice() |
Consumes v |
Shrinks excess capacity and returns a 16-byte Box<[T]> |
Common pitfall: The argument to v.reserve(additional) is the number of additional elements beyond v.len(), not the new total capacity! If v.len() == 10 and v.capacity() == 16, calling v.reserve(10) ensures total capacity is at least $10 + 10 = 20$.
Comparing reserve(), reserve_exact(), and shrink_to_fit()
fn main() {
let mut v = vec![1, 2, 3]; // len = 3, cap = 3
// 1. `reserve_exact(7)` requests exact capacity for 3 + 7 = 10 elements:
v.reserve_exact(7);
println!("After reserve_exact(7): len={}, cap={}", v.len(), v.capacity());
// 2. `reserve(50)` reserves space for at least 3 + 50 = 53 elements:
v.reserve(50);
println!("After reserve(50): len={}, cap={}", v.len(), v.capacity());
// 3. `shrink_to(8)` lowers capacity to 8 while keeping all 3 elements:
v.shrink_to(8);
println!("After shrink_to(8): len={}, cap={}", v.len(), v.capacity());
// 4. `shrink_to_fit()` drops all remaining excess capacity:
v.shrink_to_fit();
println!("After shrink_to_fit(): len={}, cap={}", v.len(), v.capacity());
}
After reserve_exact(7): len=3, cap=10
After reserve(50): len=3, cap=53
After shrink_to(8): len=3, cap=8
After shrink_to_fit(): len=3, cap=3
Freezing a Growable Vec<T> into Box<[T]>
When a Vec<T> is finished growing and will remain fixed-length for the rest of its lifetime, calling v.into_boxed_slice() calls shrink_to_fit() and converts the 24-byte Vec<T> (ptr, len, capacity) into a 16-byte Box<[T]> (ptr, len), eliminating both unused heap capacity and the 8-byte capacity field on the stack.