A masterclass in stripping the elitist gatekeeping from systems programming by making Rust’s most daunting memory concepts feel like common sense. It proves that true expertise lies in simplifying the complex rather than hiding behind academic jargon.
Deep Dive
Prerequisite Knowledge
- No data available.
Where to go next
- No data available.
Deep Dive
83: Let's Learn About "Box" & "Rc" in Rust
Added:How's it going everyone? Today, we're going to learn about smart pointers in Rust. There are a few of them out there and they each solve a different problem.
We're going to start with the simplest one, box, and then work our way up to the more complex stuff. Now, the most common reason you'd reach for box is to use trait objects. A trait object is basically a value where the concrete type gets erased at runtime. What you're left with is just the trait methods.
Boxes are usually written as box dynamic trait and that lets you store different types in the same collection. So, next we're going to create a quick example.
And here we're going to define a shape trait and implement it for a couple of types and then store all of them in the same vector. Now, this shape trait will contain one method, which gives us back the area as an F64. Below, we will create a struct called circle and this holds the radius of the circle. Next, we will implement the shape for the circle.
Here, we need to compute the area of the circle and to get the area, we just need to use pi times the radius squared. And we're going to do the same thing for a square, which will contain a side of type F64.
Then once again, we will implement the shape for the square and this requires us to implement the area method. And to get the area of a square, we just need to multiply the side by itself. Now, we can move on to the main function. Here, we're going to create some shapes, which will be of type vector box and pass in the dynamic shape and that will equal a vector, which contains the following shapes. One which is a circle and one which is a square. And we will be using the box constructor for both of these.
The main idea here is that a vector which contains a box of dynamic shapes can hold any type that implements shape, even if those types are different sizes.
This works because box contains a pointer to that object, and pointer sizes are known at compile time. So, even though a circle and a square take up different amounts of memory, this [snorts] box wrapping ensures that each one is always the same fixed size. So, once again, here we have a vector of boxed trait objects. Then inside we have a circle which is boxed, so it fits in the vector. And we did the same thing for the square. Now, if we wanted to, we could even iterate over each boxed shape.
And inside here we could print the area.
Now, when we run this, what we should end up with is 12.5 and 9 based on the information we provided here.
But now let's look at another classic use case for box, which is recursive types. A recursive type is one that contains another value of the same type.
Think of a tree where each node has more nodes inside it. The thing is, Rust needs to know the size of every type at compile time. So, if you try to make a recursive type naively, the size would be infinite.
Box solves this because it gives us a fixed-size pointer. Now, below the binary tree we're going to create a leaf, and this is just a helper method which we will use to build a leaf node.
So, inside we will return a node with no children. Now, we can build a small binary tree. So, here we will let our tree be of type binary tree, and that will equal a binary tree node. And the root node will have a value of one. Then we will create the left subtree. And finally, we will insert the right subtree. And let's format all of this so that you can see the data more clearly.
At the bottom, we will print the tree.
And now when we run this, we're going to get our tree back.
So, as you can see, boxes are quite useful.
So, in the last file, we used box to build a tree. Each node has one parent, but sometimes you need a graph instead.
A node can have multiple parents, and the graph can even have loops.
Now, box can't handle that because it only lets you have a single owner. If two nodes both pointed to the same child with box, the second assignment would move the child out of the first node, which is obviously not what we want. So, that's where RC comes in. It stands for reference counted. Every time you clone it, the count goes up. Every time it gets dropped, the count goes down. When the count hits zero, the data gets freed. Basically, it gives us shared ownership, and the only run time cost is the counter itself. So, for this example, we're going to create a node, which will be the node in our graph. And this will contain the value stored in the node. This node will also contain some neighbors, which will be a vector of type RC, which wraps a node. Inside main, we're going to build a small graph. So, let's do that by creating the shared node first, which is D. And D has no neighbors. And honestly, to make this easier to visualize, I'm going to leave this graph up here. So, right now we created D. Then below, we're going to create both B and C. Both B and C point to D, as you can see inside the vector, which we included inside our neighbors.
So right now, B and C are pointing to D.
Our C clone bumps the count each time.
So D is shared, but it's not copied.
Then we have one more node, which is node A, and A points to both B and C. As you can see inside the neighbors, we have an RC clone of B and an RC clone of C. And at the bottom, we will print these owners and the graph starting from A. What you should note here is that D has three owners, which are the original D binding, B's neighbors list, and C's neighbors list. And to prove that, we will run this so that you can see inside the console that D has three owners. And below, we get the graph printed.
Now, this graph is what we call a DAG.
That means no loops, but a graph can also have loops, where a node points back to one of its ancestors.
When that happens, you get a reference cycle, and we'll learn how to handle that shortly. And one more thing, RC only works on a single thread, and you can't mutate data through it. For those cases, we've got something called RefCell and Arc, which we'll see in the next few videos.
Related Videos

TOP 15 Data compression Interview Questions and Answers 2019 Part-2 | Data compression | Wisdom jobs
wisdomjobs
281 views•2019-06-28

CTS 158: 802.11w Management Frame Protection
ClearToSend
4K views•2019-02-04

NDSS 2019 Send Hardest Problems My Way: Probabilistic Path Prioritization for Hybrid Fuzzing
NDSSSymposium
496 views•2019-04-02

How realistic is Cities: Skylines?
CityBeautiful
159K views•2019-02-14

GUIs & TUIs: Choosing a User Interface for Your Python Project | Real Python Podcast
realpython
2K views•2025-04-04

The OSI Model - Explained by Example
hnasr
225K views•2019-05-12

Cloud Computing - Introduction
elithecomputerguy
98K views•2019-10-07

From Traveler's Dilemma to Dynamic Routing | Demystifying Networking
IITBombayJuly
5K views•2019-08-04
Trending

WOW! Judge TURNS THE TABLES on Trump in His OWN $10B LAWSUIT!!!
MeidasTouch
197K views•2026-07-23

Playstation NO DISC/NO BUY Fight Is Over...
DavidJaffeGames
4K views•2026-07-23

Steam and Xbox Just Dropped The Hammer On PlayStation
OhNoItsAlexx
9K views•2026-07-23

Americans Confused in Australia for 17 Minutes Straight
IWrocker
17K views•2026-07-23