Home
Rust
Box Examples (Vector, Array)
Updated Nov 15, 2023
Dot Net Perls
Box. To use a struct instance, we must first allocate it. By default, allocation is done on the stack region of memory—this is faster unless too many objects are created.
Box new. We can wrap a struct in the Box type. The Box will manage the memory of its enclosing type on its own—it will handle allocation, and delete the memory as well.
into_boxed_slice
Input and output. Suppose we want to create a Vector of structs. The struct name is BirdInfo, and it contains information about birds. We can use Box for the vector.
HEAP: Box<BirdInfo> Box<BirdInfo> STACK: BirdInfo BirdInfo
Box example. We have 2 versions of similar code. We add several BirdInfo structs to each vector, and print their contents at the end of main().
vec
Version 1 This code creates a Vector of Box types. It calls "Box::new" to create each element, and pushes the Boxes to the vector.
Version 2 This code use stack allocation, which is the default. It directly allocates the BirdInfo structs, without Box.
#[derive(Debug)] struct BirdInfo<'a> { color: &'a str, size: i32 } fn main() { // Version 1: allocate structs with Box on heap. let mut birds: Vec<Box<BirdInfo>> = Vec::new(); for i in 0..2 { birds.push(Box::new(BirdInfo { color: "blue", size: 4 })); } // Version 2: allocate structs on stack. let mut birds2: Vec<BirdInfo> = Vec::new(); for i in 0..2 { birds2.push(BirdInfo { color: "red", size: 5 }); } // Print results. println!("HEAP: {:?}", birds); println!("STACK: {:?}", birds2); }
HEAP: [BirdInfo { color: "blue", size: 4 }, BirdInfo { color: "blue", size: 4 }] STACK: [BirdInfo { color: "red", size: 5 }, BirdInfo { color: "red", size: 5 }]
Box array. How can we create an array of Boxes? It is not possible to initialize the array with a constant Box, as Box does not implement the Copy trait.
However We can create an array of Boxes (or boxed slices) by creating a vector of Boxes, and then converting the vector into an array.
Step 1 We create the vector of Boxes. For our example, we just push a Box of the numbers 0 through 9 inclusive.
Step 2 We convert the vector into an array. We must use try_into() as the conversion can fail if the vector size is not correct.
fn main() { // Step 1: Create a vector of boxes. let mut values = vec![]; for i in 0..10 { values.push(Box::new(i)); } // Step 2: Convert vector into array. let array: [Box<i32>; 10] = values.try_into().unwrap(); println!("{}", array.len()); }
10
Memory size optimization. With Box, we move memory to a separate location on the heap. This can improve performance when a struct is used in hot code.
Here We move the 1000-element array allocation to a separate place in the heap.
And This reduces memory usage of the struct from 1000 to 8 bytes. For some access patterns this can speed up code.
struct Example { array: [u8; 1000] } struct ExampleWithBox { array: Box<[u8; 1000]> } fn main() { println!("size of Example: {}", std::mem::size_of::<Example>()); println!("size of ExampleWithBox: {}", std::mem::size_of::<ExampleWithBox>()); }
size of Example: 1000 size of ExampleWithBox: 8
A summary. By using Box, we change how structs are allocated—Box places elements on the heap instead of the stack. This changes performance, and is more useful for larger, long-lived data.
Dot Net Perls is a collection of pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Nov 15, 2023 (edit).
Home
Changes
© 2007-2025 Sam Allen