From bcf3921a2aaf72c0f7a3e052dd2ef20f188054a3 Mon Sep 17 00:00:00 2001 From: Mike Marcacci Date: Fri, 7 Aug 2015 23:13:08 -0700 Subject: [PATCH] Added arrows to references in tables 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 `~`). --- src/doc/trpl/the-stack-and-the-heap.md | 266 ++++++++++++------------- 1 file changed, 133 insertions(+), 133 deletions(-) diff --git a/src/doc/trpl/the-stack-and-the-heap.md b/src/doc/trpl/the-stack-and-the-heap.md index cfab268a7c5..e4317f9c399 100644 --- a/src/doc/trpl/the-stack-and-the-heap.md +++ b/src/doc/trpl/the-stack-and-the-heap.md @@ -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 | -|-----------------|------|----------------| -| 230 | | 5 | -| ... | ... | ... | -| 1 | y | 42 | -| 0 | x | 230 | +| Address | Name | Value | +|-----------------|------|------------------| +| 230 | | 5 | +| ... | ... | ... | +| 1 | y | 42 | +| 0 | x | → 230 | We have 230 in our hypothetical computer with 1GB of RAM. And since our stack grows from zero, the easiest place to allocate memory is from the @@ -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 | -|----------------------|------|----------------------| -| 230 | | 5 | -| (230) - 1 | | | -| (230) - 2 | | | -| (230) - 3 | | 42 | -| ... | ... | ... | -| 3 | y | (230) - 3 | -| 2 | y | 42 | -| 1 | y | 42 | -| 0 | x | 230 | +| Address | Name | Value | +|----------------------|------|------------------------| +| 230 | | 5 | +| (230) - 1 | | | +| (230) - 2 | | | +| (230) - 3 | | 42 | +| ... | ... | ... | +| 3 | y | → (230) - 3 | +| 2 | y | 42 | +| 1 | y | 42 | +| 0 | x | → 230 | In this case, we’ve allocated four things on the heap, but deallocated two of them. There’s a gap between 230 and (230) - 3 which isn’t @@ -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 @@ -366,29 +366,29 @@ fn main() { First, we call `main()`: -| Address | Name | Value | -|-----------------|------|----------------| -| 230 | | 20 | -| ... | ... | ... | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|-----------------|------|------------------| +| 230 | | 20 | +| ... | ... | ... | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 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 | -|-----------------|------|----------------| -| 230 | | 20 | -| ... | ... | ... | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|-----------------|------|-----------------| +| 230 | | 20 | +| ... | ... | ... | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230| +| 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, @@ -396,51 +396,51 @@ since `j` points at `h`. Next, `foo()` calls `baz()`, passing `z`: -| Address | Name | Value | -|-----------------|------|----------------| -| 230 | | 20 | -| ... | ... | ... | -| 7 | g | 100 | -| 6 | f | 4 | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|-----------------|------|------------------| +| 230 | | 20 | +| ... | ... | ... | +| 7 | g | 100 | +| 6 | f | → 4 | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 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 | -|-----------------|------|----------------| -| 230 | | 20 | -| ... | ... | ... | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|-----------------|------|------------------| +| 230 | | 20 | +| ... | ... | ... | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 0 | h | 3 | Next, `foo()` calls `bar()` with `x` and `z`: -| Address | Name | Value | -|----------------------|------|----------------------| -| 230 | | 20 | -| (230) - 1 | | 5 | -| ... | ... | ... | -| 10 | e | 9 | -| 9 | d | (230) - 1 | -| 8 | c | 5 | -| 7 | b | 4 | -| 6 | a | 0 | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|----------------------|------|------------------------| +| 230 | | 20 | +| (230) - 1 | | 5 | +| ... | ... | ... | +| 10 | e | → 9 | +| 9 | d | → (230) - 1 | +| 8 | c | 5 | +| 7 | b | → 4 | +| 6 | a | → 0 | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 0 | h | 3 | We end up allocating another value on the heap, and so we have to subtract one from 230. It’s easier to just write that than `1,073,741,823`. In any @@ -448,70 +448,70 @@ case, we set up the variables as usual. At the end of `bar()`, it calls `baz()`: -| Address | Name | Value | -|----------------------|------|----------------------| -| 230 | | 20 | -| (230) - 1 | | 5 | -| ... | ... | ... | -| 12 | g | 100 | -| 11 | f | 9 | -| 10 | e | 9 | -| 9 | d | (230) - 1 | -| 8 | c | 5 | -| 7 | b | 4 | -| 6 | a | 0 | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|----------------------|------|------------------------| +| 230 | | 20 | +| (230) - 1 | | 5 | +| ... | ... | ... | +| 12 | g | 100 | +| 11 | f | → 9 | +| 10 | e | → 9 | +| 9 | d | → (230) - 1 | +| 8 | c | 5 | +| 7 | b | → 4 | +| 6 | a | → 0 | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 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 | -|----------------------|------|----------------------| -| 230 | | 20 | -| (230) - 1 | | 5 | -| ... | ... | ... | -| 10 | e | 9 | -| 9 | d | (230) - 1 | -| 8 | c | 5 | -| 7 | b | 4 | -| 6 | a | 0 | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|----------------------|------|------------------------| +| 230 | | 20 | +| (230) - 1 | | 5 | +| ... | ... | ... | +| 10 | e | → 9 | +| 9 | d | → (230) - 1 | +| 8 | c | 5 | +| 7 | b | → 4 | +| 6 | a | → 0 | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 0 | h | 3 | Next, we return from `bar()`. `d` in this case is a `Box`, so it also frees what it points to: (230) - 1. -| Address | Name | Value | -|-----------------|------|----------------| -| 230 | | 20 | -| ... | ... | ... | -| 5 | z | 4 | -| 4 | y | 10 | -| 3 | x | 0 | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|-----------------|------|------------------| +| 230 | | 20 | +| ... | ... | ... | +| 5 | z | → 4 | +| 4 | y | 10 | +| 3 | x | → 0 | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 0 | h | 3 | And after that, `foo()` returns: -| Address | Name | Value | -|-----------------|------|----------------| -| 230 | | 20 | -| ... | ... | ... | -| 2 | j | 0 | -| 1 | i | 230 | -| 0 | h | 3 | +| Address | Name | Value | +|-----------------|------|------------------| +| 230 | | 20 | +| ... | ... | ... | +| 2 | j | → 0 | +| 1 | i | → 230 | +| 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.