通过一个例子简单理解rust的生命周期与内存安全性

建议配合官方文档the book一起食用

fn main() {  
    let mut result_ref = &mut 0;
    *result_ref = 1;
    {
        let num1 = 1;
        let mut num2 = 2;
        let arg1 = &num1;
        {
            let arg2 = &mut num2;
            result_ref = lifetime(arg1, arg2);
        }
        println!("Hello, {}!", result_ref);
    }
    *result_ref = 233; // UAF occurs here
}

fn lifetime<'a>(_x: &i32, y: &'a mut i32) -> &'a mut i32 {  
    y
}

无法编译,因为当试图赋值233的时候,访问result_ref指向的地址(前面作用域结束时已经被释放的num2)是非法的。

error[E0597]: `num2` does not live long enough  
  --> src\main.rs:9:24
   |
9  |             let arg2 = &mut num2;  
   |                        ^^^^^^^^^ borrowed value does not live long enough
...
13 |     }  
   |     - `num2` dropped here while still borrowed
14 |     *result_ref = 233;  
   |     ----------------- borrow later used here

lifetime的签名保证了result_ref(地址)只在num2有效的作用域里有效。但是,但是,但是,仅此而已,虽然result_ref的值是一个非法的地址,但result_ref本身还在作用域内是可以被访问的。


稍作修改: result_ref = &mut 233; 这次试图把一个存储字面量233的新地址赋给result_ref,成功编译,输出: Hello, 2!

点击右边的按钮加载评论,如果无法加载那估计是被墙啦..你看着办w