Skip to content

Commit

Permalink
Added arrows to references in tables
Browse files Browse the repository at this point in the history
Keeping integer values and integer references in the "value" columns made the examples quite difficult for me to follow. I've added unicode arrows to make references more obvious, without using a character with actual meaning in the rust language (like `&` or previously `~`).
  • Loading branch information
mike-marcacci committed Aug 8, 2015
1 parent e5d90d9 commit bcf3921
Showing 1 changed file with 133 additions and 133 deletions.
266 changes: 133 additions & 133 deletions src/doc/trpl/the-stack-and-the-heap.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,12 @@ on the heap. The actual value of the box is a structure which has a pointer to
it allocates some memory for the heap, and puts `5` there. The memory now looks
like this:

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 5 |
| ... | ... | ... |
| 1 | y | 42 |
| 0 | x | 2<sup>30</sup> |
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 5 |
| ... | ... | ... |
| 1 | y | 42 |
| 0 | x | 2<sup>30</sup> |

We have 2<sup>30</sup> in our hypothetical computer with 1GB of RAM. And since
our stack grows from zero, the easiest place to allocate memory is from the
Expand All @@ -242,17 +242,17 @@ freed in any order, it can end up with ‘holes’. Here’s a diagram of the me
layout of a program which has been running for a while now:


| Address | Name | Value |
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 5 |
| (2<sup>30</sup>) - 1 | | |
| (2<sup>30</sup>) - 2 | | |
| (2<sup>30</sup>) - 3 | | 42 |
| ... | ... | ... |
| 3 | y | (2<sup>30</sup>) - 3 |
| 2 | y | 42 |
| 1 | y | 42 |
| 0 | x | 2<sup>30</sup> |
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 5 |
| (2<sup>30</sup>) - 1 | | |
| (2<sup>30</sup>) - 2 | | |
| (2<sup>30</sup>) - 3 | | 42 |
| ... | ... | ... |
| 3 | y | (2<sup>30</sup>) - 3 |
| 2 | y | 42 |
| 1 | y | 42 |
| 0 | x | 2<sup>30</sup> |

In this case, we’ve allocated four things on the heap, but deallocated two of
them. There’s a gap between 2<sup>30</sup> and (2<sup>30</sup>) - 3 which isn’t
Expand Down Expand Up @@ -304,22 +304,22 @@ fn main() {

When we enter `main()`, memory looks like this:

| Address | Name | Value |
|---------|------|-------|
| 1 | y | 0 |
| 0 | x | 5 |
| Address | Name | Value |
|---------|------|--------|
| 1 | y | → 0 |
| 0 | x | 5 |

`x` is a plain old `5`, and `y` is a reference to `x`. So its value is the
memory location that `x` lives at, which in this case is `0`.

What about when we call `foo()`, passing `y` as an argument?

| Address | Name | Value |
|---------|------|-------|
| 3 | z | 42 |
| 2 | i | 0 |
| 1 | y | 0 |
| 0 | x | 5 |
| Address | Name | Value |
|---------|------|--------|
| 3 | z | 42 |
| 2 | i | → 0 |
| 1 | y | → 0 |
| 0 | x | 5 |

Stack frames aren’t just for local bindings, they’re for arguments too. So in
this case, we need to have both `i`, our argument, and `z`, our local variable
Expand Down Expand Up @@ -366,152 +366,152 @@ fn main() {

First, we call `main()`:

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

We allocate memory for `j`, `i`, and `h`. `i` is on the heap, and so has a
value pointing there.

Next, at the end of `main()`, `foo()` gets called:

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|-----------------|------|-----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | → 4 |
| 4 | y | 10 |
| 3 | x | → 0 |
| 2 | j | → 0 |
| 1 | i | 2<sup>30</sup>|
| 0 | h | 3 |

Space gets allocated for `x`, `y`, and `z`. The argument `x` has the same value
as `j`, since that’s what we passed it in. It’s a pointer to the `0` address,
since `j` points at `h`.

Next, `foo()` calls `baz()`, passing `z`:

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 7 | g | 100 |
| 6 | f | 4 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 7 | g | 100 |
| 6 | f | 4 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

We’ve allocated memory for `f` and `g`. `baz()` is very short, so when it’s
over, we get rid of its stack frame:

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

Next, `foo()` calls `bar()` with `x` and `z`:

| Address | Name | Value |
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

We end up allocating another value on the heap, and so we have to subtract one
from 2<sup>30</sup>. It’s easier to just write that than `1,073,741,823`. In any
case, we set up the variables as usual.

At the end of `bar()`, it calls `baz()`:

| Address | Name | Value |
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 12 | g | 100 |
| 11 | f | 9 |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 12 | g | 100 |
| 11 | f | 9 |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

With this, we’re at our deepest point! Whew! Congrats for following along this
far.

After `baz()` is over, we get rid of `f` and `g`:

| Address | Name | Value |
|----------------------|------|----------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|----------------------|------|------------------------|
| 2<sup>30</sup> | | 20 |
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
| 10 | e | 9 |
| 9 | d | (2<sup>30</sup>) - 1 |
| 8 | c | 5 |
| 7 | b | 4 |
| 6 | a | 0 |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

Next, we return from `bar()`. `d` in this case is a `Box<T>`, so it also frees
what it points to: (2<sup>30</sup>) - 1.

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 5 | z | 4 |
| 4 | y | 10 |
| 3 | x | 0 |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

And after that, `foo()` returns:

| Address | Name | Value |
|-----------------|------|----------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |
| Address | Name | Value |
|-----------------|------|------------------|
| 2<sup>30</sup> | | 20 |
| ... | ... | ... |
| 2 | j | 0 |
| 1 | i | 2<sup>30</sup> |
| 0 | h | 3 |

And then, finally, `main()`, which cleans the rest up. When `i` is `Drop`ped,
it will clean up the last of the heap too.
Expand Down

0 comments on commit bcf3921

Please sign in to comment.