在Rust中,堆栈上发生了什么,堆上发生了什么?

时间:2018-10-02 20:58:26

标签: rust

我对Rust的内存分配系统感到非常困惑。

在Java中,您使用new在堆上分配内存。在C中,您使用malloc(),其他所有内容都进入堆栈。

我认为,在Rust中,Box<T>在堆上分配内存,但是在读取"Defining Our Own Smart Pointer" section in chapter 15.2 in The Rust Programming Language之后,似乎MyBox<T>并没有任何特殊的注释来使{{1 }}放在堆上。

  1. 堆栈中到底发生了什么,堆中到底发生了什么?

  2. T的实现与MyBox<T>基本上相同吗?

  3. 如果实现相同,是什么使Box<T>存储在堆而不是堆栈中?

  4. 如果实现方式不同,是什么使T在堆上分配内存?

1 个答案:

答案 0 :(得分:5)

  1. 这很难说。通常,Rust避免在堆上分配任何东西。编译器永远不会在堆上进行隐式分配,但是库函数可以为您完成此分配。至少任何具有动态大小的东西(例如Vec<T>)都需要在引擎盖下的堆上放置一些东西,其余的,文档应该提示它。

    请注意,即使在C语言中,许多函数也可以执行堆分配而无需显式调用malloc。例如。最近,我不得不调试一个内存泄漏,其中开发人员叫getaddrinfo而没有相应的freeaddrinfo,而忽略了该函数在堆上分配内存的情况。得益于RAII,此类锈病在Rust中应该很少见。

  2. 一点都不!这本书正在简化这里的内容,以避免对本节不重要的细节。

  3. Box是内置的编译器。在幕后分配内存的是在liballoc中定义的分配器。您可以认为此分配器提供了类似malloc的功能。实际上,默认分配器在大多数目标上使用jemalloc,也可以使用自定义分配器,例如alloc_system板条箱使用系统的malloc / realloc / free用于构建其分配器。