-
Notifications
You must be signed in to change notification settings - Fork 24
翻譯The Stack and the Heap #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
3442853561
wants to merge
5
commits into
askeing:master
Choose a base branch
from
3442853561:翻譯The-Stack-and-the-Heap
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
The head ref may contain hidden characters: "\u7FFB\u8B6FThe-Stack-and-the-Heap"
Open
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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語言是一個在底層運轉的系統語言。如果您只學習過高級語言則可能不太熟悉這方面的內容。 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 中文與英文間建議間隔一個半形空白。 |
||
| 使用堆疊和堆積是內存工作的一個最重要的途徑。 | ||
| 如果您熟知那些和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 | ||
| # 內存管理 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| These two terms are about memory management. The stack and the heap are | ||
| abstractions that help you determine when to allocate and deallocate memory. | ||
|
|
@@ -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: | ||
|
|
||
|
|
@@ -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 | | ||
|
|
@@ -116,7 +112,7 @@ value being stored. | |
|
|
||
| After `foo()` is over, its frame is deallocated: | ||
|
|
||
| | Address | Name | Value | | ||
| | 位址 | Name | Value | | ||
| |---------|------|-------| | ||
| | 0 | x | 42 | | ||
|
|
||
|
|
@@ -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**| | ||
|
|
@@ -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** | | ||
|
|
@@ -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**| | ||
|
|
@@ -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 | ||
|
|
@@ -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 | ?????? | | ||
|
|
@@ -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 | | ||
| | ... | ... | ... | | ||
|
|
@@ -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 | | | | ||
|
|
@@ -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 | ?????? | | ||
|
|
@@ -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 | | ||
|
|
@@ -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 | | ||
|
|
@@ -377,7 +373,7 @@ fn main() { | |
|
|
||
| First, we call `main()`: | ||
|
|
||
| | Address | Name | Value | | ||
| | 位址 | Name | Value | | ||
| |----------------------|------|------------------------| | ||
| | (2<sup>30</sup>) - 1 | | 20 | | ||
| | ... | ... | ... | | ||
|
|
@@ -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 | | ||
| | ... | ... | ... | | ||
|
|
@@ -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 | | ||
| | ... | ... | ... | | ||
|
|
@@ -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 | | ||
| | ... | ... | ... | | ||
|
|
@@ -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 | | ||
|
|
@@ -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 | | ||
|
|
@@ -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 | | ||
|
|
@@ -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 | | ||
| | ... | ... | ... | | ||
|
|
@@ -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 | | ||
| | ... | ... | ... | | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
此處應該有漏字?