简体   繁体   English

Rust是否有可能造成memory泄漏?

[英]Is it possible to cause a memory leak in Rust?

Is there any way of causing a memory leak in Rust?有什么方法可以在 Rust 中导致 memory 泄漏? I know that even in garbage-collected languages like JavaScript there are edge-cases where memory will be leaked, are there any such cases in Rust?我知道即使在像 JavaScript 这样的垃圾收集语言中,也存在 memory 会泄漏的边缘情况,Rust 中是否存在此类情况?

Yes, leaking memory in Rust is as easy as calling the std::mem::forget function.是的,在 Rust 中泄漏内存就像调用std::mem::forget函数一样简单。

You can also leak memory if you create a cycle of shared references :如果创建共享引用循环,也可能会泄漏内存:

A cycle between Rc pointers will never be deallocated. Rc指针之间的循环永远不会被释放。 For this reason, Weak is used to break cycles.因此, Weak用于中断循环。 For example, a tree could have strong Rc pointers from parent nodes to children, and Weak pointers from children back to their parents.例如,一棵树可能具有从父节点到子节点的强Rc指针,以及从子节点返回到其父节点的Weak指针。

You can also useBox::leak to create a static reference, or Box::into_raw in an FFI situation.您还可以使用Box::leak创建静态引用,或在FFI情况下使用Box::into_raw


Actually, in a system programming language, you need to be able to create a memory leak, otherwise, for example in an FFI case, your resource would be freed after being sent for use in another language.实际上,在系统编程语言中,您需要能够创建内存泄漏,否则,例如在 FFI 情况下,您的资源在发送以供其他语言使用后将被释放。


All those examples show that a memory leak does not offend the memory safety guaranteed by Rust.所有这些例子都表明内存泄漏并没有违反 Rust 保证的内存安全。 However, it is safe to assume that in Rust, you do not have any memory leak, unless you do a very specific thing.但是,可以安全地假设在 Rust 中,您没有任何内存泄漏,除非您执行非常具体的操作。

Also, note that if you adopt a loose definition of the memory leak, there are infinite ways to create one, for example, by adding some data in a container without releasing the unused one.另请注意,如果您对内存泄漏采用松散的定义,则有无数种方法可以创建内存泄漏,例如,通过在容器中添加一些数据而不释放未使用的数据。

From the book书中

Rust's memory safety guarantees make it difficult, but not impossible, to accidentally create memory that is never cleaned up (known as a memory leak). Rust 的内存安全保证使得意外创建永远不会被清理的内存(称为内存泄漏)变得困难,但并非不可能。 Preventing memory leaks entirely is not one of Rust's guarantees in the same way that disallowing data races at compile time is, meaning memory leaks are memory safe in Rust.完全防止内存泄漏不是 Rust 的保证之一,就像在编译时禁止数据竞争一样,这意味着内存泄漏在 Rust 中是内存安全的。

So the answer is yes.所以答案是肯定的。 You can have memory leaks in your code and rust compiler won't complain about it.您的代码中可能存在内存泄漏,而 Rust 编译器不会抱怨它。

use std::rc::Rc;
use std::cell::{RefCell};

Rc creates a smart pointer to count the references. Rc创建一个智能指针来计算引用。 Similar to how garbage collector counts references.类似于垃圾收集器如何计算引用。 Since Rc hold shared reference it is always immutable因为Rc持有共享引用,所以它总是immutable

Refcell is also a smart pointer that represents single ownership over the data but the ownership rule is checked at run time not at compile time. Refcell也是一个智能指针,表示对数据的单一所有权,但所有权规则是在运行时而不是编译时检查的。 with Refcell we can get a mutable reference of an immutable variable.使用Refcell我们可以获得不可变变量的可变引用。

let x=32;
let x1=&mut x;

Normally, this is not allowed because x is immutable and we are getting a mutable reference to it.通常情况下,这是不允许的,因为 x 是不可变的,我们正在获取对它的可变引用。 But with Refcell we get this power.但是有了Refcell ,我们获得了这种力量。

Together, wrapping Refcell with Rc we can create shared reference which can mutate the data.一起,用Rc包装Refcell我们可以创建可以改变数据的共享引用。

After this intro, this code will create memory leakage:在此介绍之后,此代码将产生 memory 泄漏:

use std::rc::Rc;
use std::cell::{RefCell};

#[derive(Debug)]
struct Node{
    next:Option<Rc<RefCell<Node>>>,
}
fn main(){
    let a=Rc::new(RefCell::new(Node{next:None}));
    let b=Rc::new(RefCell::new(Node{next:Some(Rc::clone(&a))}));
    let c=Rc::new(RefCell::new(Node{next:Some(Rc::clone(&b))}));
    // we do not have any cycles so far

    // after this line we have cycle. a-> b -> c -> a
    (*a).borrow_mut().next=Some(Rc::clone(&c));
    println!("a {:?}",a);
}

when you print "a", a points to b which points to c which points a again, so will see this in the terminal:当您打印“a”时,a 指向 b,b 指向 c,后者再次指向 a,因此将在终端中看到:

在此处输入图像描述

You can read here Reference Cycles Can Leak Memory您可以在这里阅读Reference Cycles Can Leak Memory

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM