MST
星途 面试题库

面试题:Rust内存模型中所有权的核心概念及应用

请阐述Rust内存模型中所有权的核心概念,并举例说明在实际编程中如何利用所有权机制避免内存泄漏和悬空指针问题。
10.4万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

Rust内存模型中所有权的核心概念

  1. 所有权:在Rust中,每一个值都有一个变量作为其所有者。在同一时刻,一个值只能有一个所有者。当所有者超出其作用域时,该值将被释放。
  2. 移动(Move):当一个值被赋予另一个变量,或者作为参数传递给函数时,所有权会发生移动。这意味着原来的变量不再拥有该值的所有权,新的变量成为所有者。
  3. 借用(Borrowing):允许在不转移所有权的情况下访问值。分为不可变借用(使用&符号)和可变借用(使用&mut符号)。但有一个规则,在同一作用域内,要么只能有一个可变借用,要么可以有多个不可变借用,不能同时存在可变借用和不可变借用。
  4. 生命周期:描述了引用保持有效的作用域。编译器会通过生命周期检查来确保引用在其生命周期内始终有效。

实际编程中利用所有权机制避免内存泄漏和悬空指针问题的示例

fn main() {
    // 避免内存泄漏
    let s1 = String::from("hello");
    // s1 拥有这个字符串的所有权
    let s2 = s1;
    // s1 的所有权移动到 s2,此时 s1 不再有效,避免了内存泄漏,因为 Rust 会在 s2 超出作用域时释放内存

    // 避免悬空指针
    let mut s3 = String::from("world");
    let r1 = &s3;
    // r1 是对 s3 的不可变借用
    // 这里不能对 s3 进行修改,因为有不可变借用 r1 存在
    println!("{}", r1);

    let r2 = &mut s3;
    // r2 是对 s3 的可变借用
    // 此时不能有其他对 s3 的借用(包括不可变借用)
    *r2 = String::from("new world");
    println!("{}", r2);
    // 当 r1 和 r2 超出作用域后,它们不再引用 s3,避免了悬空指针问题
}

在这个例子中,通过所有权的移动避免了内存泄漏,因为Rust确保只有一个变量在任何时刻拥有资源的所有权,并且在所有者超出作用域时释放资源。通过借用规则避免了悬空指针问题,编译器会确保引用始终指向有效的对象,在同一时间只有符合规则的借用才被允许。