Consider the following piece of code:
fn main() { let a = 32; let b = &a; }
We have created two variable bindings, with the second one (b) pointing at the address for a. The b variable doesn't contain the value of the a variable, but it points to the position a is held at, from which it can obtain a value (in other words, the value of b is borrowed from a).
In terms of our stack diagram, we have this:
Function name |
Address |
Variable name |
Value |
main |
1 |
b |
→ address 0 |
0 |
a |
32 |
If we have a function call another function, but with a parameter, our stack will look slightly different:
fn second(i: &i32) { let c = 42; println!("{}", *i); } fn main() { let a = 32; let b = &a; second(b); }
Function name |
Address |
Variable name |
Value |
3 |
c |
42 |
|
second |
2 |
i |
→ address 0 |
1 |
b |
→ address 0 |
|
main |
0 |
a |
32 |
The i binding points to address 0 and the b variable points to address 0, and this is the parameter being passed to second.
We can use this stack method to think about memory for a complex situation if you like.