解引用裸指针
创建指针是安全的操作,但解引用指针需要使用 unsafe
方法:
fn main() {
let mut s = String::from("careful!");
let r1 = &mut s as *mut String;
let r2 = r1 as *const String;
// SAFETY: r1 and r2 were obtained from references and so are guaranteed to
// be non-null and properly aligned, the objects underlying the references
// from which they were obtained are live throughout the whole unsafe
// block, and they are not accessed either through the references or
// concurrently through any other pointers.
unsafe {
println!("r1 is: {}", *r1);
*r1 = String::from("uhoh");
println!("r2 is: {}", *r2);
}
// NOT SAFE. DO NOT DO THIS.
/*
let r3: &String = unsafe { &*r1 };
drop(s);
println!("r3 is: {}", *r3);
*/
}
This slide should take about 10 minutes.
我们建议(而且 Android Rust 样式指南要求)为每个 unsafe
代码块编写一条注释, 说明该代码块中的代码如何满足其所执行的不安全操作的 安全要求。
对于指针解除引用,这意味着指针必须为 valid,即:
- 指针必须为非 null。
- 指针必须是 dereferenceable(在单个已分配对象的边界内)。
- 对象不得已取消分配。
- 不得并发访问相同位置。
- 如果通过转换引用类型来获取指针,则底层对象必须处于活跃状态, 而且不得使用任何引用来访问内存。
在大多数情况下,指针还必须正确对齐。
The “NOT SAFE” section gives an example of a common kind of UB bug: *r1
has the 'static
lifetime, so r3
has type &'static String
, and thus outlives s
. Creating a reference from a pointer requires great care.