【问题标题】:Where is a struct that doesn't implement Copy allocated and how can it be returned from a function?不实现 Copy 的结构在哪里分配,如何从函数中返回?
【发布时间】:2020-11-24 16:00:09
【问题描述】:

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

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

#[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);
}

例如,在第 12 行,在 bar() 函数的堆栈帧中分配了一个 Foo 结构。当bar() 退出时,堆栈被展开,内存被回收。由于struct没有实现Copy,所以内存没有被复制,那么它去哪里了呢?

我认为这里有一个我不明白的基本概念。

【问题讨论】:

    标签: memory-management rust


    【解决方案1】:

    Everything1 以某种方式存储在堆栈中。即使你堆分配了一些东西,指针本身也存储在堆栈中。

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

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

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

    值可以通过复制位复制的类型。

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

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


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

    2 — 优化器实际上可能通过在 parent 的 堆栈帧中分配结构来开始并传递一个指针来移除移动进入孩子。这称为返回值优化

    3 — 存在无法移动值的病态情况。请参阅Why can't I store a value and a reference to that value in the same struct? 的“引用自身的类型”部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-03
      • 2017-04-23
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 1970-01-01
      相关资源
      最近更新 更多