 GeeksforGeeks App
Open App Browser
Continue

# Rust – Box Smart Pointer

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),``    ``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)))`

My Personal Notes arrow_drop_up