< 返回版块

Louys·Miaoa 豆沙饼 发表于 2021-12-19 17:32

Tags:drop,pointer

问题一:第19行后, 局部变量a已经drop了,为什么23行unsafe还能取到原来a的值10?难道是i32 Copy语义作祟?

问题二:按道理我猜想a在栈上d出栈drop后,原位置应该是b补上,在23行unsafe打印为什么不是15 而是10呢?


Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=496f3fe1c8c75fb0e0db296d3f056b4e

评论区

写评论
Grobycn 2021-12-19 19:45

drop并不会回收内存,回收内存需要在实现复杂的内存管理,显然在栈上不合适。

比如下面的代码, d, e 是直接压栈方便,还是把 e 分配到 b 的地址方便。

以上是我的理解

struct A<T>(T);

impl<T> Drop for A<T> {
    fn drop(&mut self) {}
}

fn main() {
    let a = A(i32);
    let b = A(i8);
    let c = A(i16);
    drop(b);
    let d = A(i16);
    let e = A(i8);
}
eric642 2021-12-19 18:33

猜测依据: c++的函数的局部变量(放在栈上的变量)的释放其实是由操作系统退栈的时候自动释放的. 估计rust也是同理. 猜测: 这段代码并没有形成一个函数栈, 所以a虽然看似已经出了作用域, 但是并没有被操作系统释放, 而unsafe绕过了rust的规则,所以还可以使用.

    {
        let a = A(10);
        println!("a address {:p}", &a);
        p = &a;
        println!("b address {:p}", p);
    }
苦瓜小仔 2021-12-19 17:56

解引用裸指针 意味着:

  • 允许忽略借用规则,可以同时拥有不可变和可变的指针,或多个指向相同位置的可变指针
  • 不保证指向有效的内存
  • 允许为空
  • 不能实现任何自动清理功能
1 共 3 条评论, 1 页