Description
I was reviewing some code that uses split_off(0)
in a loop to take the contents of a buffer, while leaving the buffer's capacity intact to be reused by subsequent iterations. When I double-checked the actual behaviour of split_off(0)
, I was surprised to find that the vector returned by split_off(0)
had a much larger capacity than was necessary to hold its contents.
Consider this example program: (playground link)
fn main() {
let mut buffer = Vec::with_capacity(100);
buffer.extend([1u8, 2u8]);
println!("buffer capacity: {}", buffer.capacity());
println!();
let split_off_1 = buffer.split_off(1);
println!("split_off_1 capacity: {}", split_off_1.capacity());
println!("buffer capacity: {}", buffer.capacity());
println!();
let split_off_0 = buffer.split_off(0);
println!("split_off_0 capacity: {}", split_off_0.capacity());
println!("buffer capacity: {}", buffer.capacity());
println!();
}
I expected that the split_off_1
and split_off_0
vectors would have similar capacities, since they each only hold one value.
Instead, this happened:
buffer capacity: 100
split_off_1 capacity: 1
buffer capacity: 100
split_off_0 capacity: 100
buffer capacity: 100
The single-element vector produced by split_off(1)
has a tight capacity of 1, but the single-element vector produced by split_off(0)
has a wasteful capacity of 100, which is the same as the original vector's capacity.
(The method's documentation doesn't make any explicit promises about the capacity of the returned vector, so this isn't necessarily a bug per se, but it is a surprising behaviour.)