diff --git a/src/chapter_3/chapter_3_7_2.md b/src/chapter_3/chapter_3_7_2.md index 75dc110..ec2c0ac 100644 --- a/src/chapter_3/chapter_3_7_2.md +++ b/src/chapter_3/chapter_3_7_2.md @@ -241,3 +241,42 @@ int main() 在执行第14行前,其内存布局为: ![注释](../../assets/11.png) + +当执行第14行后,变成如下: + +![注释](../../assets/12.png) + +第14行执行后,ptr就变成了一个悬垂指针(或者交悬垂引用),然后在第16行继续使用ptr,则会发生错误。 + +- 在 Rust 中,编译器确保引用永远不会变成悬垂状态。 + +如下代码因为会产生悬垂引用,编译将不会通过: +```Rust +fn main() { + let reference_to_nothing = dangle(); +} +fn dangle() -> &String { + let s = String::from("hello"); + &s // s在花括号前离开作用域,将会变得无效,返回的指向s的引用将是一个悬垂引用 +} +``` + +*思考:为什么下面的代码是正确的* ? +```Rust +fn main() { + let s = no_dangle(); + println!("s = {:?}", s); +} + +fn no_dangle() -> String { + let s = String::from("hello"); + s +} // 此处s虽然离开了函数这个作用域范围,但是它的所有权是被转移出去了,值并没有释放 +``` + +#### 4. 引用的规则总结 +引用的规则可以总结如下: + +- 在任意给定时间,要么 只能有一个可变引用,要么 只能有多个不可变引用。 +- 引用必须总是有效的(不能是悬垂引用)。 +