< 返回版块

leslieDD 发表于 2021-05-19 14:25

如题...

#[derive(Debug)]
struct DianDian {
    name: String,
}

fn main(){
    let a = 1;
    drop(a);
    println!("a is {}", a);  // 正常

    let dd = DianDian {
        name: String::from(""),
    };
    drop(dd);
    println!("dd is {:?}", dd); // 出错:value borrowed here after move
}

是不是说能正常drop掉的,都是堆上的,不能drop的是在栈上的

评论区

写评论
viruscamp 2021-05-20 09:41

我认为变量一定是在栈上的, 有意义的应该是 借用 指针 智能指针 型的变量, 其指向的数据在堆上还是在栈上。

追踪数据的所有者,当所有者未为空的 Box Rc Arc String Vec 那么数据一定在堆上。

Boxinto_rawleak 泄露出的指针,借用其内容一定在堆上, 这些在使用时已无法追踪其所有者。

FFI unsafe 等手段造成的堆上数据, 使用时无法追踪, 只能读代码找其创建方式。

苦瓜小仔 2021-05-19 19:24

这种基础问题去自己看标准库的文档。基础的语法问题文档和书就能解决。

给你几个关键词 Copy trait、Clone trait、Drop trait

给你一些提示:

在堆的数据上一定不会是 Copy 语义的。

栈上的数据可能是 Copy 的,也可能是 非 Copy 的。

Copy trait 和 Drop trait 是互斥的。非 Copy 语义的数据就会被 Drop 掉。

kkonghao 2021-05-19 17:39

可以看指针的增长方向,另外drop并不是真正的drop 只是不让你用了而已,看下标准库的文档

c5soft 2021-05-19 17:24

a与dd变量是放在栈(stack)上的,而dd中name是一个指针,指向堆(heap)上的分配的一块内存。

c5soft 2021-05-19 17:18

a不是没有drop掉,而是编译器做了特殊处理,这里:

  println!("a is {}", a);  // 正常

经过优化,等同于

  println!("a is {}", 1); 

也可以理解为,编译器对实现了copy trait的变量,自动复制了一份,相当于:

let a1=a.clone();
  println!("a is {}", a1); 


--
👇
zombie110year: 基本类型默认使用了 Copy 特性。你的 let a = 1 实际上没有被消耗掉。

Peacess 2021-05-19 15:15

原理是这样的,堆与栈的内存地址是不一样的,所以可以通过判断变量的内存地址来判断, 至于堆与栈的内存地址我也没有,可以在网上找找看,在代码中怎么取得它们的范围

zombie110year 2021-05-19 15:09

基本类型默认使用了 Copy 特性。你的 let a = 1 实际上没有被消耗掉。

1 共 7 条评论, 1 页