Rust 如何保证内存安全并防止段错误? [英] How does Rust guarantee memory safety and prevent segfaults?

查看:73
本文介绍了Rust 如何保证内存安全并防止段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种语言来学习,我发现 Rust 变得非常流行.

I was looking for a language to learn, and I saw that Rust is getting quite popular.

关于 Rust,有两点让我印象深刻,内存安全和防止段错误.

Two things impressed me about Rust, memory safety and preventing segfaults.

Rust 是如何做到这一点的?例如,Rust 和 Java 之间的哪些区别启用了 Rust 的安全功能?

How does Rust achieve this? What differences between Rust and Java for example enable Rust's safety features?

推荐答案

Rust 如何实现内存安全,就其核心而言,实际上非常简单.它主要取决于两个原则:所有权和借款.

How Rust achieves memory safety is, at its core, actually quite simple. It hinges mainly on two principles: ownership and borrowing.

所有权

编译器使用仿射类型系统来跟踪每个值的所有权:一个值最多只能使用一次,之后编译器拒绝再次使用它.

The compiler uses an affine type system to track the ownership of each value: a value can only be used at most once, after which the compiler refuses to use it again.

fn main() {
    let original = "Hello, World!".to_string();
    let other = original;
    println!("{}", original);
}

产生错误:

error[E0382]: use of moved value: `original`
 --> src/main.rs:4:20
  |
3 |     let other = original;
  |         ----- value moved here
4 |     println!("{}", original);
  |                    ^^^^^^^^ value used here after move
  |
  = note: move occurs because `original` has type `std::string::String`, which does not implement the `Copy` trait

这尤其可以防止在 C 或 C++ 中经常遇到的可怕的double-free(在智能指针出现之前).

This, notably, prevents the dreaded double-free regularly encountered in C or C++ (prior to smart pointers).

借用

来自 Rust 的启示是当混合别名和可变性时会发生内存问题:也就是说,当可以通过多个路径访问单个内存并且它发生变异(或移开)时会留下悬垂指针.

The illumination that comes from Rust is that memory issues occur when one mixes aliasing and mutability: that is, when a single piece of memory is accessible through multiple paths and it is mutated (or moved away) leaving behind dangling pointers.

因此借用检查的核心原则是:Mutability XOR Aliasing.原则上类似于读写锁.

The core tenet of borrow checking is therefore: Mutability XOR Aliasing. It's similar to a Read-Write Lock, in principle.

这意味着 Rust 编译器会跟踪 别名 信息,为此它使用 生命周期注释(那些 'a&'a var) 将引用的生命周期和它们引用的值连接在一起.

This means that the Rust compiler tracks aliasing information, for which it uses the lifetime annotations (those 'a in &'a var) to connect the lifetime of references and the value they refer to together.

如果有人引用了某个值或 INTO 值(例如,对 struct 的字段或集合的元素的引用),则该值被借用.借来的值不能移动.

A value is borrowed if someone has a reference to it or INTO it (for example, a reference to a field of a struct or to an element of a collection). A borrowed value cannot be moved.

可变性(无别名)

您在任何时候都只能获得一个可变引用(&mut T)到一个给定值中,而没有不可变引用成这个值可能同时存在;它保证您可以独占访问这部分内存,因此您可以安全地对其进行变异.

You can obtain only a single mutable reference (&mut T) into a given value at any time, and no immutable reference into this value may exist at the same time; it guarantees that you have exclusive access to this tidbit of memory and thus you can safely mutate it.

别名(无可变性)

您可以随时获取多个不可变引用(&T)到一个给定值中.但是,您不能通过这些引用 (*) 更改任何内容.

You can obtain multiple immutable references (&T) into a given value at any time. However you cannot mutate anything through those references (*).

(*) 我在撒谎;有像 RefCell 这样的结构实现了内部可变性";他们确实尊重可变异或别名原则,但将检查推迟到运行时.

(*) I am lying; there are structs like RefCell which implement "interior mutability"; they do respect the Mutability XOR Aliasing principle, but defer the check to run-time instead.

就这样?

差不多;)

对于编译器编写者来说实现起来已经相当复杂,并且可能会过度约束用户(一些安全的程序在使用这个系统时不能被证明是安全的,需要跳过箍),但是核心原则是真的就这么简单.

It is already quite complicated to implement for the compiler-writers, and may unduly constrain the users (some programs that would be safe cannot be proven safe using this system, requiring to jump through hoops), however the core principles are really that simple.

还剩下什么?

边界检查.这不是火箭科学,但可能会导致性能下降.大多数语言都对它有一定程度的支持,C 是一个很大的例外,而 C++ 对它有一些支持,尽管它是可选的.

Bounds-checking. It is not rocket-science, but may induce a performance penalty though. Most languages have some degree of support for it, C being the big exception, and C++ having some support for it, although it is optional.

这篇关于Rust 如何保证内存安全并防止段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆