Open In App

Rust – Box Smart Pointer

Improve
Improve
Like Article
Like
Save
Share
Report

Box allows us to store data in the heap contrary to the default scheme of Rust to store as a stack.

Box is basically used for:

  • For dynamic allocation of memory for variables.
  • When there is a lot of data that we need to transfer ownership and we don’t want that they are copied.

Let’s create a box to store i32 value in a heap.

Example:

Rust




fn main() {
    let num = Box::new(4);
    println!("num = {}", num);
}


Output:

num = 4

Using Box<T> for Recursive Type:

We will be using a cons list to create a list of values. cons list takes two values the first one is the current value and the other is the next value, it performs a recursive call to cons function to generate a list, where the base condition for the recursive call is Nil.

Example:

Rust




enum List {
    Cons(i32, List),
    Nil,
}
use crate::List::{Cons, Nil};
  
fn main() {
    let list = Cons(1, Cons(2, Cons(3, Nil)));
}


It won’t compile because the List variable size cannot be determined prior to compilation.

Output:

 rustc -o main main.rs
error[E0072]: recursive type `List` has infinite size
 --> main.rs:1:1
  |
1 | enum List {
  | ^^^^^^^^^ recursive type has infinite size
2 |     Cons(i32, List),
  |               ---- recursive without indirection
  |
  = help: insert indirection (e.g., a `Box`, `Rc`, or `&`) at some point to make `List` representable

error[E0391]: cycle detected when processing `List`
 --> main.rs:1:1
  |
1 | enum List {
  | ^^^^^^^^^
  |
  = note: ...which again requires processing `List`, completing the cycle
  = note: cycle used when computing dropck types for `Canonical { max_universe: U0, variables: [], value: ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing, def_id: None }, value

There is an error that tells the List has infinite size because the compiler cannot determine the size of List during compilation. So we will be using a pointer to the list rather than the list itself to overcome this error. Since the size of the pointer is fixed irrespective of the data type to which it is pointing, therefore the compiler can determine its size during compilation. Let’s see this implementation using Box<T>.

Example:

Rust




// for printing complex data types
#[derive(Debug)] 
enum List {
    Cons(i32, Box<List>),
    Nil,
}
  
use crate::List::{Cons, Nil};
  
fn main() {
    let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
    println!("{:?}",list)
}


Output:

Cons(1, Cons(2, Cons(3, Nil)))


Last Updated : 30 Jul, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads