当所有权转移发生时内存中会发生什么

问题描述 投票:0回答:1

我正在努力完全掌握所有权转移过程中内存部分会发生什么。 如果一个值由一个变量拥有并转移到另一个变量,则转移后原始变量的堆栈帧中的内存会发生什么情况

举个例子,t超出了范围,但测试仍然有效。 Test(1) 存储在哪里,如果它在堆栈中创建,那么在块结束后它如何仍然有效?

struct Test(u8);

impl Drop for Test {
   fn drop(&mut self) {
      println!("{} is dropped", self.0);
  }
}

fn main() {
   let test;
   {
       println!("step 1");
       let t = Test(1);
       println!("step 2");
       test = t;
   } 
   println!("{}", test.0);
}

输出:

step 1
step 2
1
1 is dropped

当所有者超出范围时,Rust 通过回收内存自动清理与该所有者关联的数据。 这是一个似乎与之矛盾的例子:

fn main() {
   println!("step 1");
   let test = create_struct();
   println!("step 2");
   println!("{}", test.0);
}

pub fn create_struct() -> Test {
   Test(1)
}

输出:

step 1 
step 2 
1 
1 is dropped 

如果当所有者超出范围时回收内存,那么从函数返回值如何防止这种情况发生?

从第一个示例的输出来看,它没有被复制,因为只删除了一个 Test 实例,这也意味着堆栈内存没有在内部块中回收,或者这里发生了什么?

rust ownership
1个回答
0
投票

免责声明:由于优化,内存中实际发生的情况很难确定。例如,变量根本不需要存储在内存中,它可以存储在 CPU 寄存器中。这个答案的其余部分假设变量以“明显”的方式存储在内存中。

如果一个值由一个变量拥有并转移到另一个变量,则转移后原始变量的堆栈帧中的内存会发生什么情况

它保持未使用状态(或通过优化重新用于存储其他变量)。

举个例子,t超出了范围,但测试仍然有效。 Test(1) 存储在哪里,如果它在堆栈中创建,那么在块结束后它如何仍然有效?

它首先存储在

t
中,然后移动(按位复制)到
test
。移动后,
t
中的记忆不再相关。

如果当所有者超出范围时回收内存,那么从函数返回值如何防止这种情况发生?

它通过将值移动到另一个位置来防止这种情况。如果你只是调用

create_struct();
而不将值分配给任何东西,它确实会被丢弃。通过将其分配给变量,可以有效地延长其寿命。

从第一个示例的输出来看,它没有被复制,因为只删除了一个 Test 实例

这是正确的 - 它没有被复制,而是被移动了。与 C++ 不同,Rust 不执行隐式复制,您必须显式调用

.clone()
,然后移动 that 值。

这也意味着堆栈内存没有在内部块中回收,或者这里发生了什么?

函数返回后,堆栈内存就会被回收。在此之前,由于堆栈的工作原理,移动或删除值不会回收内存。

© www.soinside.com 2019 - 2024. All rights reserved.