![625267ad5bedfb9c26da06e6a193e0b9.png](https://img-blog.csdnimg.cn/img_convert/625267ad5bedfb9c26da06e6a193e0b9.png)
Rust承诺:引用始终有效。
可是,Rust引用并没有堆变量的生杀大权“Ownership”,对于堆变量,只能借来用用,充其量借来改改(再还回去),那么Rust是如何保障引用的权益呢?
在面对悬挂引用问题之前,我们先复习下Rust引用。
一 引用的内存模型
fn main() {
let s1 = String::from("hello");
let len = calculate_length(&s1);
println!("The length of '{}' is {}.", s1, len);
}
fn calculate_length(s: &String) -> usize {
s.len()
}
上面代码里,堆上有一个String“hello”,在栈上有对应其所有权变量s1,以及一个临时的引用借用s。代码内存模型如下:
![04f0c3ec7a4f32a315417806ff6b03b8.png](https://img-blog.csdnimg.cn/img_convert/04f0c3ec7a4f32a315417806ff6b03b8.png)
s和s1,是两种不同的类型,可以用下面的代码把类型打印来看。之所以s和s1用起来没差别,是因为引用s能自动解引用。
fn print_type_of<T>(_: &T) {
println!("{}", std::any::type_name::<T>())
}
fn main() {
let s1 = String::from("hello");
let s = &s1;
print_type_of(& s1);
print_type_of(& s);
}
![0297d809aa3f96c94fc095c3ceb76862.png](https://img-blog.csdnimg.cn/img_convert/0297d809aa3f96c94fc095c3ceb76862.png)
二 悬挂引用问题
在C++里,当我们说到指针带来的内存安全问题时,就会提到
- 空指针(null pointer):指针值为Null;
- 野指针(wild pointer):未经初始化的“垃圾值”地址;
- 悬挂指针(dangling pointer):指向已经释放的地址;
在Rust里,由于没有空值Null,所以并没有空引用问题;编译期进行初始化检查,所以也没有野引用问题。那么再看悬挂,Rus