Skip to content

裸指针

创建裸指针

rust
fn main() {
    let mut num = 5;

    // 创建裸指针
    let r1 = &num as *const i32;  // 不可变裸指针
    let r2 = &mut num as *mut i32;  // 可变裸指针

    println!("r1: {:?}", r1);
    println!("r2: {:?}", r2);

    // 裸指针可以是 null
    let null_ptr: *mut i32 = std::ptr::null_mut();
    println!("null: {:?}", null_ptr);
}
▶ Run

裸指针 vs 引用

┌─────────────────────────────────────────────────────┐
│          裸指针 vs 引用                              │
├─────────────────────────────────────────────────────┤
│                                                     │
│  引用 (&T, &mut T):                                │
│  • 始终有效(不能是 null)                          │
│  • 遵循借用规则                                     │
│  • 自动清理                                         │
│  • 安全                                             │
│                                                     │
│  裸指针 (*const T, *mut T):                        │
│  • 可以是 null                                      │
│  • 不遵循借用规则                                   │
│  • 没有自动清理                                     │
│  • 解引用需要 unsafe                                │
│                                                     │
└─────────────────────────────────────────────────────┘

解引用裸指针

rust
fn main() {
    let mut num = 5;
    let ptr = &mut num as *mut i32;

    // 解引用需要 unsafe
    unsafe {
        println!("解引用:{}", *ptr);
        *ptr = 10;
        println!("修改后:{}", *ptr);
    }

    println!("num = {}", num);  // 10
}
▶ Run

裸指针操作

rust
fn main() {
    let mut arr = [1, 2, 3, 4, 5];
    let ptr = arr.as_mut_ptr();

    unsafe {
        // 读取
        println!("{}", ptr.read());

        // 写入
        ptr.write(10);

        // 偏移
        let second = ptr.add(1);
        println!("{}", second.read());

        // 复制
        std::ptr::copy_nonoverlapping(ptr, ptr.add(1), 4);
    }

    println!("{:?}", arr);
}
▶ Run