This commit is contained in:
lcofjp 2017-11-29 22:57:14 +08:00
parent 2b591ea224
commit 55205dcc92

View File

@ -171,7 +171,7 @@ let s2 = s1;
之前,我们提到过当变量离开作用域后 Rust 自动调用 `drop` 函数并清理变量的堆内存。不过图 4-4 展示了两个数据指针指向了同一位置。这就有了一个问题:当 `s2``s1` 离开作用域,他们都会尝试释放相同的内存。这是一个叫做 *double free* 的错误,也是之前提到过的内存安全性 bug 之一。两次释放(相同)内存会导致内存污染,它可能会导致潜在的安全漏洞。 之前,我们提到过当变量离开作用域后 Rust 自动调用 `drop` 函数并清理变量的堆内存。不过图 4-4 展示了两个数据指针指向了同一位置。这就有了一个问题:当 `s2``s1` 离开作用域,他们都会尝试释放相同的内存。这是一个叫做 *double free* 的错误,也是之前提到过的内存安全性 bug 之一。两次释放(相同)内存会导致内存污染,它可能会导致潜在的安全漏洞。
为了确保内存安全,这种场景下 Rust 的处理有另一个细节值得注意。与其尝试拷贝被分配的内存Rust 则认为 `s1` 不再有效,因此 Rust 不需要在 `s1` 离开作用域后清理任何东西。看看在 `s2` 被创建之后尝试使用 `s1` 会发生么: 为了确保内存安全,这种场景下 Rust 的处理有另一个细节值得注意。与其尝试拷贝被分配的内存Rust 则认为 `s1` 不再有效,因此 Rust 不需要在 `s1` 离开作用域后清理任何东西。看看在 `s2` 被创建之后尝试使用 `s1` 会发生么:
```rust,ignore ```rust,ignore
let s1 = String::from("hello"); let s1 = String::from("hello");
@ -195,7 +195,7 @@ error[E0382]: use of moved value: `s1`
which does not implement the `Copy` trait which does not implement the `Copy` trait
``` ```
如果你在其他语言中听说过术语 “浅拷贝”“shallow copy”和 “深拷贝”“deep copy”那么拷贝指针、长度和容量而不拷贝数据可能听起来像浅拷贝。不过因为 Rust 同时使第一个变量无效化了,这个操作被称为 **移动***move*),而不是浅拷贝。上面的例子可以解读为 `s1`**移动** 到了 `s2` 中。那么具体发生了什么如图 4-6 所示。 如果你在其他语言中听说过术语 “浅拷贝”“shallow copy”和 “深拷贝”“deep copy”那么拷贝指针、长度和容量而不拷贝数据可能听起来像浅拷贝。不过因为 Rust 同时使第一个变量无效化了,这个操作被称为 **移动***move*),而不是浅拷贝。上面的例子可以解读为 `s1`**移动** 到了 `s2` 中。那么具体发生了什么如图 4-6 所示。
<img alt="s1 moved to s2" src="img/trpl04-04.svg" class="center" style="width: 50%;" /> <img alt="s1 moved to s2" src="img/trpl04-04.svg" class="center" style="width: 50%;" />