我真的对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>似乎没有任何特殊的注释来使T的值在堆上有效.

  1. 堆栈上到底有什么,堆上到底有什么?

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

  3. 如果实现是相同的,那么是什么让T存储在堆上而不是堆栈上?

  4. 如果实现不一致,那么是什么让Box<T>在堆上分配内存?

推荐答案

  1. 这很难说.通常避免在堆上分配任何内容.编译器永远不会在堆上执行隐式分配,但may库函数可以为您执行.至少任何动态大小的东西(例如Vec<T>)都需要在堆中的引擎盖下放置一些东西,对于其他东西,文档应该会给出提示.

    注意,即使在C语言中,许多函数也可以在不显式调用malloc的情况下进行堆分配.我最近不得不调试一个内存泄漏,一个开发人员调用了getaddrinfo,却没有相应的freeaddrinfo,忽略了这个函数在堆上分配内存.然而,多亏了RAII,这类虫子在Rust 中应该非常罕见.

  2. 一点也不!这本书简化了这里的内容,避免了对本节不重要的细节.

  3. -

  4. Box是一个内置的编译器.在引擎盖下,分配内存的是一个在liballoc中定义的分配器.您可以认为这个分配器提供了类似malloc的功能.实际上,默认分配器在大多数目标上使用jemalloc,也可以使用自定义分配器,例如alloc_system crate 使用系统的malloc/realloc/free函数来构建其分配器.

Rust相关问答推荐

if let声明中临时对象的生存期

收集RangeInclusive T到Vec T<><>

展开枚举变量并返回所属值或引用

为什么允许我们将可变引用转换为不可变引用?

在决定使用std::Sync::Mutex还是使用Tokio::Sync::Mutex时,操作系统线程调度是考虑因素吗?

在IntoIter上调用.by_ref().Take().rev()时会发生什么情况

如何实现Deref;多次;?

为什么 vec![Vec::with_capacity(n)] 为子向量创建 0 容量?

为什么我需要 to_string 函数的参考?

如何从宏调用闭包?

如何在 Rust 中打印 let-else 语句中的错误?

返回优化后的标题:返回异步块的闭包的类型擦除

Rust typestate 模式:实现多个状态?

在 Rust 中,我如何处理请求 javascript 的页面?

切片不能被 `usize` 索引?

在 Rust 中,将可变引用传递给函数的机制是什么?

`use std::error::Error` 声明中断编译

实现不消费的迭代器

匹配结果时的简洁日志(log)记录

如何在 Rust 中构建一个 str