Smart pointers in Cairo are advanced data structures that ensure safe and efficient memory management by adding safety features to regular pointers, preventing common issues like dereferencing null pointers or accessing uninitialized memory.
A smart pointer behaves like a regular pointer but tracks ownership and ensures safe memory access, preventing issues like null or dangling pointer dereferencing.
Cairo provides several smart pointer types, such as Box<T>
and Nullable<T>
:
Box<T>
: Stores data in a special memory segment, ideal for large or dynamically-sized data.
It allows transferring ownership without copying the data.Nullable<T>
: Points to either a valid value of type T
or null
, useful for handling optional values.Smart pointers help prevent unsafe memory access, ensuring memory is automatically deallocated when no longer needed, thus reducing the risk of memory leaks.
Box<T>
for Recursive TypesSmart pointers like Box<T>
allow for safe handling of recursive types, such as in a binary tree, by allocating memory efficiently and avoiding infinite recursion.
use core::box::{BoxTrait};
#[derive(Copy, Drop)]
enum BinaryTree {
Leaf: u32,
Node: (u32, Box<BinaryTree>, Box<BinaryTree>),
}
fn main() {
let leaf1 = BinaryTree::Leaf(1);
let leaf2 = BinaryTree::Leaf(2);
let node = BinaryTree::Node((3, BoxTrait::new(leaf1), BoxTrait::new(leaf2)));
println!("{:?}", node);
}
Smart pointers improve performance by passing references to data instead of copying large structures, reducing memory overhead.
// `Cart` is a large struct that contains a lot of information
fn pass_pointer(cart: Box<Cart>) {
let cart = cart.unbox();
println!("{} is shopping today and bought {} items", cart.buyer, cart.items);
}
In Chrono Realms, Time Keepers often deal with not just trees of timelines, but Chrono Chains-sequences of linked TimeNodes, each representing a specific moment in time. A Chrono Chain is a straight path of sequential moments, where each TimeNode connects to the next. These Chrono Chains are useful when traveling through a series of specific events, as they allow Time Keepers to follow a single timeline.
However, to handle these potentially long Chrono Chains, Time Keepers use Smart Pointers (Box<t>)</t> to safely manage and traverse these lists of moments without causing unnecessary memory duplication or overflow. Each TimeNode holds a reference to the next node, forming a recursive structure.
Your task as an apprentice is to implement a Chrono Chain as a recursive list structure using smart pointers.
In this exercise, you will:
ChronoChain
enum, representing a list of moments.Box<T>
smart pointer to store the recursive nodes.ChronoChain
from an array of u32
values.ChronoChain
and sum up the values stored in the list.ChronoChain
EnumCreate a recursive enum ChronoChain
with two variants:
End
: Represents the end of the list.Link
: Contains a u32
value and a boxed reference to the next node in the chain.Write a function ChronoChain::build
that takes an array of u32
values and returns a ChronoChain
, linking the values sequentially using smart pointers.
Write a function ChronoChain::sum
to recursively traverse the ChronoChain
and sum the values of all nodes.
fn main() {
// Create a ChronoChain from an array of values
let chrono_chain = ChronoChain::build(array![10, 20, 30]);
// Sum the values in the ChronoChain
let total_sum = chrono_chain.sum();
println!("Total Time Power: {}", total_sum);
}
Sign up to Exercism to learn and master Cairo with 68 exercises, and real human mentoring, all for free.