Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/MappingTable.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,18 @@ zero-cost abstractions | 無成本抽象化 |

English 英文 | Traditional Chinese 正體中文 | Note 備註
------------ |----------------------------- |----------
address | | 暫時譯為地址
alignment | |
backtrace | |
bootstrap | |
build | | 名詞,例:create a "build"
closures | |
commit | | git commit
crates | |
crates | | 有的譯本中翻譯為箱
dependencies | |
destructuring let | | 用於存取 tuple
fully-strict | |
hash | |
hash | | 有的譯本中翻譯為
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

此處應該有漏字?

import | |
linker | |
linking | |
Expand All @@ -203,7 +204,7 @@ prelude | | 預先載入的函式
profiles | |
regression | |
repository | |
root | |
root | | 有的譯本中翻譯為根
shell | |
slices | | 其他資料結構的參考
tabs | |
Expand Down
76 changes: 36 additions & 40 deletions src/the-stack-and-the-heap.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
% The Stack and the Heap
% 堆疊與堆積

As a systems language, Rust operates at a low level. If you’re coming from a
high-level language, there are some aspects of systems programming that you may
not be familiar with. The most important one is how memory works, with a stack
and a heap. If you’re familiar with how C-like languages use stack allocation,
this chapter will be a refresher. If you’re not, you’ll learn about this more
general concept, but with a Rust-y focus.
Rust語言是一個在底層運轉的系統語言。如果您只學習過高級語言則可能不太熟悉這方面的內容。
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

中文與英文間建議間隔一個半形空白。
Ref: 中文文案排版指南

使用堆疊和堆積是內存工作的一個最重要的途徑。
如果您熟知那些和C語言相似的程式語言的話這一章的內容講更新您對堆疊和堆積的認識。
如果您還不了解這部分的內容,本章將會帶您以 Rust 語言的視角來了解它們。

As with most things, when learning about them, we’ll use a simplified model to
start. This lets you get a handle on the basics, without getting bogged down
with details which are, for now, irrelevant. The examples we’ll use aren’t 100%
accurate, but are representative for the level we’re trying to learn at right
now. Once you have the basics down, learning more about how allocators are
implemented, virtual memory, and other advanced topics will reveal the leaks in
this particular abstraction.
和平常一樣,我們將會通過一個簡明的模型來著手學習它們。
這是為了讓您著手基礎知識而不是糾結那些目前而言無關緊要的細節。
這個例子並不是絕對的準確無誤。它只代表我們現在正在學習的水準。
一旦您掌握了這些基礎之後,學習了更多有關於分配器的實作、
虛擬記憶體、以及其他進階的主題,將會揭露出這些特定的抽象概念。

# Memory management
# 內存管理
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Memory 應翻為 記憶體


These two terms are about memory management. The stack and the heap are
abstractions that help you determine when to allocate and deallocate memory.
Expand All @@ -27,7 +23,7 @@ But the allocation is local to a function call, and is limited in size. The
heap, on the other hand, is slower, and is explicitly allocated by your
program. But it’s effectively unlimited in size, and is globally accessible.

# The Stack
# 堆疊

Let’s talk about this Rust program:

Expand Down Expand Up @@ -89,15 +85,15 @@ number comes from 2<sup>30</sup>, the number of bytes in a gigabyte. [^gigabyte]
This memory is kind of like a giant array: addresses start at zero and go
up to the final number. So here’s a diagram of our first stack frame:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

We’ve got `x` located at address `0`, with the value `42`.

When `foo()` is called, a new stack frame is allocated:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| 2 | z | 100 |
| 1 | y | 5 |
Expand All @@ -116,7 +112,7 @@ value being stored.

After `foo()` is over, its frame is deallocated:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

Expand Down Expand Up @@ -153,13 +149,13 @@ We have some kooky function names to make the diagrams clearer.

Okay, first, we call `main()`:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

Next up, `main()` calls `bold()`:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| **3** | **c**|**1** |
| **2** | **b**|**100**|
Expand All @@ -168,7 +164,7 @@ Next up, `main()` calls `bold()`:

And then `bold()` calls `italic()`:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| *4* | *i* | *6* |
| **3** | **c**|**1** |
Expand All @@ -180,7 +176,7 @@ Whew! Our stack is growing tall.
After `italic()` is over, its frame is deallocated, leaving only `bold()` and
`main()`:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| **3** | **c**|**1** |
| **2** | **b**|**100**|
Expand All @@ -189,14 +185,14 @@ After `italic()` is over, its frame is deallocated, leaving only `bold()` and

And then `bold()` ends, leaving only `main()`:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|-------|
| 0 | x | 42 |

And then we’re done. Getting the hang of it? It’s like piling up dishes: you
add to the top, you take away from the top.

# The Heap
# 堆積

Now, this works pretty well, but not everything can work like this. Sometimes,
you need to pass some memory between different functions, or keep it alive for
Expand All @@ -216,7 +212,7 @@ fn main() {

Here’s what happens in memory when `main()` is called:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|--------|
| 1 | y | 42 |
| 0 | x | ?????? |
Expand All @@ -228,7 +224,7 @@ 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 |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 5 |
| ... | ... | ... |
Expand All @@ -253,7 +249,7 @@ 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 |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 5 |
| (2<sup>30</sup>) - 2 | | |
Expand Down Expand Up @@ -282,7 +278,7 @@ implementation of `Drop` for `Box` deallocates the memory that was allocated
when it was created. Great! So when `x` goes away, it first frees the memory
allocated on the heap:

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|--------|
| 1 | y | 42 |
| 0 | x | ?????? |
Expand Down Expand Up @@ -315,7 +311,7 @@ fn main() {

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

| Address | Name | Value |
| 位址 | Name | Value |
|---------|------|--------|
| 1 | y | → 0 |
| 0 | x | 5 |
Expand All @@ -325,7 +321,7 @@ 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 |
| 位址 | Name | Value |
|---------|------|--------|
| 3 | z | 42 |
| 2 | i | → 0 |
Expand Down Expand Up @@ -377,7 +373,7 @@ fn main() {

First, we call `main()`:

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
Expand All @@ -390,7 +386,7 @@ value pointing there.

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

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
Expand All @@ -407,7 +403,7 @@ since `j` points at `h`.

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

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
Expand All @@ -423,7 +419,7 @@ Next, `foo()` calls `baz()`, passing `z`:
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 |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
Expand All @@ -436,7 +432,7 @@ over, we get rid of its stack frame:

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

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 2 | | 5 |
Expand All @@ -459,7 +455,7 @@ case, we set up the variables as usual.

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

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 2 | | 5 |
Expand All @@ -483,7 +479,7 @@ far.

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

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| (2<sup>30</sup>) - 2 | | 5 |
Expand All @@ -503,7 +499,7 @@ After `baz()` is over, we get rid of `f` and `g`:
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>) - 2.

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
Expand All @@ -516,7 +512,7 @@ what it points to: (2<sup>30</sup>) - 2.

And after that, `foo()` returns:

| Address | Name | Value |
| 位址 | Name | Value |
|----------------------|------|------------------------|
| (2<sup>30</sup>) - 1 | | 20 |
| ... | ... | ... |
Expand Down