Skip to content

什么是裸指针

在 Rust 中,裸指针(又叫原始指针,Raw Pointer)是一种不受 Rust 借用规则保护的指针类型。它们与 C 语言中的指针类似,只是没有经过 Rust 的安全检查和 borrow checker 的限制。使用裸指针需要特别小心,因为它们容易导致内存安全问题,如空指针、悬垂指针、非法内存访问等等。

裸指针有两种类型:*const T*mut T。前者是不可变的裸指针,后者是可变的裸指针。其中,T 是指针指向的类型,例如,*const i32 表示一个指向 i32 类型的不可变裸指针,&mut String 表示一个指向 String 类型的可变引用。

要创建一个裸指针,可以使用取地址符号 & 并将其转换为具体的裸指针类型。例如:

rust
fn main() {
    let x = 10;
    let ptr: *const i32 = &x as *const i32; // 创建一个指向 x 的不可变裸指针
}

在上述代码示例中,我们使用 &x 获取 x 的引用,并将其转换为 *const i32 类型,得到了一个指向 x 的不可变裸指针 ptr

需要注意的是,由于裸指针无法保证指向合法内存,因此在使用裸指针时,需要在 unsafe 块中进行操作,以告诉 Rust 编译器这是没有经过安全检查的操作。例如:

rust
fn main() {
    let x = 10;
    let ptr: *const i32 = &x as *const i32;

    unsafe {
        println!("The value of x is {}", *ptr);
    }
}

在上述代码示例中,我们使用 unsafe 块来解引用 ptr 指向的值,并将其打印输出。通过使用 unsafe 块,我们告诉 Rust 编译器这是一个不安全的操作,需要程序员自行承担安全风险和责任。

在 Rust 中 一个指针所指向的内容与它本身的值有什么区别?

在 Rust 中,一个指针包含两个部分:指向的内容和指针本身的值。指针本身的值表示指针所指向的内容在内存中的地址,而指向的内容是存储在该地址上的数据。

指针本身的值通常是一个整数,用于表示内存地址。在 Rust 中,指针有两种类型:裸指针(raw pointer)和引用(reference)。 引用是 Rust 中更加安全和常用的指针类型,因为它们受到语言的安全检查和借用规则的保护,避免了悬垂指针和内存不安全的问题。

当我们在 Rust 中定义一个变量时,比如 let x = 10;,它会被存储在内存中的某个地址上。这个地址也就是 x 的值。如果我们想要访问这个值,就需要使用指针或引用。

下面是一个使用引用的示例:

假设我们有一个指向 x 的裸指针 ptr,它将指向 x 存储在内存中的地址。我们可以通过解引用 *ptr 来获取指针所指向的内容,即 x 的值。下面是一个简单的示例:

rust
fn main() {
    let x = 10;
    let ptr = &x as *const i32;  // 定义一个裸指针,指向 x 所在的内存地址

    println!("ptr value: {:?}", ptr);
    println!("ptr points to value: {:?}", unsafe { *ptr });
}

在上面的代码中,我们定义了变量 x 并将其初始化为整数10。然后,我们通过 &x 获取了一个指向 x 的引用,并将其转换为一个裸指针。最后,我们输出了裸指针的值和指针所指向的内容(对裸指针的操作都是不安全的操作,需要使用unsafe块)。

对于引用,我们可以像这样定义一个指向 x 的引用 ref_xlet ref_x = &x;与裸指针不同,引用受到 Rust 的安全检查和借用规则的保护,避免了悬垂指针和内存不安全的问题。 我们也可以通过解引用 *ref_x 来获取引用所指向的内容,即 x 的值。

下面是一个使用引用的示例代码:

rust
fn main() {
    let x = 10;         // 定义一个变量 x
    let ref_x = &x;     // 定义一个指向 x 的引用 ref_x

    println!("ref_x value: {:p}", ref_x);                // 输出引用 ref_x 的值,即内存地址
    println!("ref_x points to value: {:?}", *ref_x);     // 输出引用 ref_x 指向的内容,即 x 的值
}

在上面的例子中,变量ref_x是一个指向x的引用(即:一个指向x变量的指针),它的值就是 x 在内存中的地址。可以通过 *ref_x 来访问 ref_x 指向的内容,即变量 x 的值。

需要注意的是,由于 Rust 的所有权机制,一旦一个变量的所有权被转移了,它所对应的内存区域就会被释放,因此它的指针也就失效了。 因此,在 Rust 中需要非常注意指针的安全性和生命周期。如果想要在多个地方共享数据,可以使用引用类型来传递数据的所有权而不是直接传递指针。这样可以让编译器在编译时检查所有权是否正确转移,从而避免一些常见的内存安全问题。

Released under the MIT License