为什么 Rust 认为内存泄漏是安全的?

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

根据 Rust Book 中的这一章,通过创建指针循环可能会泄漏内存:

Rust 的内存安全保证使得意外创建从未清理过的内存(称为 内存泄漏)变得困难,但并非不可能。完全防止内存泄漏并不是 Rust 的保证之一,就像在编译时禁止数据竞争一样,这意味着内存泄漏在 Rust 中是内存安全的。我们可以看到,Rust 通过使用

Rc<T>
RefCell<T>
允许内存泄漏:可以创建项目在循环中相互引用的引用。这会造成内存泄漏,因为循环中每个项目的引用计数永远不会达到 0,并且值永远不会被删除。

存在诸如“弱指针”之类的替代方案,它允许您创建自引用结构,该结构在删除时仍然可以被清理。事实上,该章后面实际上建议使用

Weak<T>

为什么 Rust 认为这是安全的?为什么在这种情况下,语言没有采取任何措施来防止“不良程序员行为”?

pointers memory-leaks rust
2个回答
23
投票

因为安全。


unsafe
在 Rust 中具有非常具体的含义,它专门针对触发未定义行为的编程错误类别。这些是最严重的错误,因为它们完全颠覆了您对程序的整体理解,使编译器或硬件以不可预测的方式运行。

内存泄漏不会触发未定义的行为,因此是安全的。

您可能对 Nomicon(《Rust Book》的 Unsafe 版本)对 Leaking 的说法感兴趣;关于

ScopeGuard
的例子通常被称为泄漏灾难。


值得注意的是,垃圾收集语言很容易泄漏内存。一个简单的

Map
,其中添加键值对而不删除将最终导致堆耗尽;并且 GC 将无法阻止它。

不断增长的

Map
与反复忘记
free
指针一样不可取,无论哪种情况都会出现堆耗尽的情况,但 GC 化的语言通常被认为是安全的。


0
投票

术语“内存泄漏”经常被误用为包括无意的对象保留,即我所说的“内存囤积”。 内存泄漏最初是指程序无法再访问的内存。 现在它已经意味着不再需要的记忆。 我不清楚这与泄漏有什么关系。

在地图示例中,程序仍然拥有对所有对象的引用,即可以找到它们。 这与 Rust 中循环列表的情况不同,当最后一个外部列表被删除时,程序会丢失对该列表的所有引用。

我想我们现在需要一个新术语来创建无法访问的内存,以便人们可以区分它和内存囤积。 内存囤积比无法访问的内存更容易找到。 也许创建无法访问的内存可以称为“内存丢弃”。

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