当所有权从盒子里转移出来时,内存中会发生什么?



print_struct中的变量s是指堆上的数据还是堆栈上的数据?

struct Structure {
x: f64,
y: u32,
/* Use a box, so that Structure isn't copy */
z: Box<char>,
}
fn main() {
let my_struct_boxed = Box::new(Structure {
x: 2.0,
y: 325,
z: Box::new('b'),
});
let my_struct_unboxed = *my_struct_boxed;
print_struct(my_struct_unboxed);
}
fn print_struct(s: Structure) {
println!("{} {} {}", s.x, s.y, s.z);
}

据我了解,let my_struct_unboxed = *my_struct_boxed;将所有权从盒子转移到my_struct_unboxed,然后在函数print_structs

实际数据会发生什么情况?最初它是通过调用Box::new(...)从堆栈复制到堆上的,但是数据是否在某个时候移动或复制回堆栈?如果是这样,如何?什么时候叫drop?当s超出范围时?

my_struct_boxed中的Structure数据存在于堆上,my_struct_unboxed中的Structure数据存在于堆栈中。

因此,天真地说(没有编译器优化(,取消引用(*(Box时的移动或复制操作将始终涉及复制数据。在借用检查器/静态分析方面,由于Copy特征没有实现Structure,这表示数据的所有权转移到my_struct_unboxed变量。

当你调用print_struct时,将发生另一个副本,它将内存中代表你的Structure的位从局部变量复制到函数的参数调用堆栈。从语义上讲,这再次表示所有权转移到print_struct函数中。

最后,当print_struct超出范围时,它会丢弃它拥有的Structure


参考资料:std::marker::Copy

摘录

需要注意的是,在这两个示例中,唯一的区别 是赋值后是否允许您访问 [您的变量]。在 Hood,复制和移动都可能导致位被复制到 内存,尽管有时会将其优化掉。

请注意最后一部分"这有时会被优化掉"。这就是为什么早期的描述被简化为假设没有编译器优化,即幼稚。在很多情况下,编译器会积极优化和内联代码,尤其是opt-level标志的值较高时。

如果是这样,如何?

">

复制"和"移动"在语义上都是memcpy的(尽管这可以优化为其他内容,甚至什么都没有(。

什么时候叫drop?当s超出范围时?

是的。当print_struct结束时,它会清理其本地范围,并删除s

最新更新