MST

星途 面试题库

面试题:Rust中原始指针解引用的安全注意事项

在Rust中,原始指针(`*const T` 和 `*mut T`)解引用时需要注意哪些安全问题?请举例说明如何避免因解引用原始指针导致的未定义行为。
25.5万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 安全问题
    • 空指针解引用:解引用空指针会导致未定义行为。例如,如果有一个*const i32类型的指针,它可能为空,如果直接解引用它,就会出现未定义行为。
    • 悬垂指针解引用:当指针所指向的内存已经被释放,再去解引用该指针,也会导致未定义行为。比如一块内存被分配给一个指针,然后这块内存被释放了,指针却没有更新,之后再解引用该指针。
    • 未初始化内存访问:如果指针指向的是未初始化的内存,解引用该指针也会导致未定义行为。
  2. 避免方法及示例
    • 检查空指针
fn main() {
    let ptr: *const i32 = std::ptr::null();
    if!ptr.is_null() {
        let value = unsafe { *ptr };
        println!("Value: {}", value);
    }
}
  • 确保内存有效:使用Box或其他内存管理类型来确保内存有效,避免悬垂指针。例如:
fn main() {
    let boxed = Box::new(42);
    let ptr: *mut i32 = boxed.as_mut();
    let value = unsafe { *ptr };
    println!("Value: {}", value);
    // 当`boxed`离开作用域时,内存会被正确释放,并且不会导致悬垂指针
}
  • 初始化内存:在使用指针前确保内存已初始化。比如使用std::mem::uninitialized创建未初始化内存后,要先初始化再解引用:
use std::mem;
fn main() {
    let mut uninit: mem::MaybeUninit<i32> = mem::MaybeUninit::uninit();
    unsafe {
        uninit.as_mut_ptr().write(42);
        let value = uninit.assume_init();
        println!("Value: {}", value);
    }
}

总之,在Rust中解引用原始指针时,必须在unsafe块中进行,并要特别注意空指针、悬垂指针以及内存初始化等安全问题。