Unsafe Rust是Rust安全子集的扩展,允许使用编译器无法验证的所有权、生命周期和别名的操作。主要应用领域包括:与低级库的交互、FFI、手动内存控制、实现不符合安全Rust模型的抽象。
Unsafe的关键特性:
unsafe { ... }或函数:unsafe fn some_func()示例:
let x: i32 = 10; let ptr: *const i32 = &x as *const i32; unsafe { println!("Value: {}", *ptr); // 解引用原始指针 }
在unsafe块内的代码是否完全不安全且不受编译器检查,或者编译器是否仍然应用借用检查器和其他检查?
答复: 不,在unsafe块内,编译器仍然检查Rust的许多规则(例如,类型、所有权规则、语法),但允许仅执行那些否则不允许的操作。不能完全禁用借用检查器!
示例:
let mut x = 0; let r1 = &mut x as *mut i32; // 被禁止: let r2 = &mut x as *mut i32; // 即使在unsafe中,若违反可变性也会出现错误
故事
在异步文件库中使用了原始指针来控制缓冲区,但忘记正确跟踪缓冲区的生命周期。结果,在关闭文件时,指针变成“悬挂的”,访问导致未定义行为(unsafe部分未能避免use-after-free)。
故事
在自己实现的类似Vec的结构中,程序员通过unsafe手动扩展缓冲区。偏移错误导致元素复制不正确和数据损坏,因为未考虑类型的对齐和布局。
故事
在线程描述符中使用了静态可变指针(static mut),没有适当的同步。因此,在多线程模式下意外出现数据竞争,导致应用程序偶发崩溃,仅通过模糊测试检测到。