没有实现复制分配的结构在哪里,如何从函数返回?

ami*_*ayh 0 memory-management rust

我读到 Rust 中的内存默认分配在堆栈上,除非通过使用 aBox或其他方法明确告诉编译器使用堆。

我知道所有权在函数调用之间移动,但实际分配的结构内存在哪里?如果它在堆栈上,当函数退出时会发生什么?

#[derive(Debug)]
struct Foo(i32);

#[derive(Debug)]
struct Bar(Foo);

fn foo() -> Foo {
    Foo(42)
}

fn bar() -> Bar {
    let f = foo();
    Bar(f)
}

fn main() {
    let bar = bar();
    println!("{:?}", bar);
}
Run Code Online (Sandbox Code Playgroud)

例如,在第 12 行,Foobar()函数的堆栈帧中分配了一个结构体。当bar()退出时,堆栈被退绕和所述存储器被回收。既然struct没有实现Copy,内存就没有被复制,那它去哪儿了呢?

我认为这里有一个我不明白的基本思想。

She*_*ter 5

所有1都以某种方式存储在堆栈中。即使在堆分配某些内容时,指针本身也存储在堆栈中。

您的FooBar实例存储在堆栈中。当函数返回实例时,数据从内部堆栈帧移到外部堆栈帧2

由于结构没有实现Copy,所以不会复制内存

这不是特征的含义Copy(强调我的):

可以简单地通过复制位来复制其值的类型。

Rust 中的所有3都可以移动。如果这不是真的,那么该语言将很难使用!您的数据从一个堆栈帧移动到另一个堆栈帧。

“复制”和“移动”之间的唯一区别是复制允许使用源值和目标值,而移动只允许使用目标值。


1 - 几乎所有东西。我希望static值实际上并未存储在堆栈中。

2 — 优化器实际上可能会通过在父级堆栈帧中分配结构体来开始移动,然后将指针传递给子级。这称为返回值优化

3 — 存在无法移动值的病理情况。请参阅为什么我不能在同一个结构中存储值和对该值的引用的“具有对自身的引用的类型”部分.