55·Unsafe Rust高级

裸指针操作

裸指针操作

学习目标

  1. 掌握裸指针的创建和操作
  2. 理解裸指针与引用的区别
  3. 掌握指针算术

核心概念

创建裸指针

fn main() {
    let mut num = 5;

    // 从引用创建(安全)
    let r1 = &num as *const i32;
    let r2 = &mut num as *mut i32;

    // 从地址创建(危险,仅用于 FFI)
    let r3 = 0x12345usize as *const i32;

    // 空指针
    let null: *const i32 = std::ptr::null();
}

解引用

fn main() {
    let mut value = 42;
    let ptr = &mut value as *mut i32;

    unsafe {
        println!("值: {}", *ptr);
        *ptr = 100;
        println!("修改后: {}", *ptr);
    }
}

指针算术

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

    unsafe {
        for i in 0..arr.len() {
            println!("arr[{}] = {}", i, *ptr.add(i));
        }
    }
}

指针与引用转换

fn main() {
    let mut value = 42;

    // 引用 → 裸指针
    let ptr = &mut value as *mut i32;

    // 裸指针 → 引用(unsafe)
    unsafe {
        let r = &mut *ptr;
        *r = 100;
    }

    println!("value = {}", value);
}

std::ptr 方法

fn main() {
    let mut a = 1;
    let mut b = 2;

    let ptr_a = &mut a as *mut i32;
    let ptr_b = &mut b as *mut i32;

    unsafe {
        // 复制
        std::ptr::copy_nonoverlapping(ptr_a, ptr_b, 1);
        println!("b = {}", b);  // 1

        // 交换
        std::ptr::swap(ptr_a, ptr_b);

        // 写入
        std::ptr::write(ptr_a, 99);
        println!("a = {}", a);  // 99
    }
}

实践练习

练习 1:手动 memcpy

fn my_copy<T: Copy>(src: *const T, dst: *mut T, count: usize) {
    unsafe {
        for i in 0..count {
            dst.add(i).write(src.add(i).read());
        }
    }
}

fn main() {
    let src = [1, 2, 3, 4, 5];
    let mut dst = [0i32; 5];
    my_copy(src.as_ptr(), dst.as_mut_ptr(), 5);
    println!("{:?}", dst);
}

小结

操作语法
创建 *const&x as *const T
创建 *mut&mut x as *mut T
解引用unsafe { *ptr }
指针算术ptr.add(n)
写入ptr.write(value)
复制std::ptr::copy

练习编辑器

rust
Loading...