Rust如何保证内存安全并防止段错误?

Myr*_*yra 12 memory-management segmentation-fault rust

我正在寻找一种学习语言,我看到Rust变得非常受欢迎.

关于Rust,内存安全和防止段错的两件事让我印象深刻.

Rust如何实现这一目标?例如,Rust和Java之间有什么区别可以实现Rust的安全功能?

Mat*_* M. 23

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

所有权

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

fn main() {
    let original = "Hello, World!".to_string();
    let other = original;
    println!("{}", original);
}
Run Code Online (Sandbox Code Playgroud)

产生错误:

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
Run Code Online (Sandbox Code Playgroud)

值得注意的是,这可以防止在C或C++中经常遇到的可怕的双重自由(在智能指针之前).

借款

来自Rust的照明是当混合别名和可变性时发生内存问题:也就是说,当一个内存可以通过多个路径访问并且它被突变(或移开)而留下悬空指针时.

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

这意味着,编译器锈迹别名信息,对于其使用寿命注解(那些'a&'a var),以引用的使用寿命,并且它们是指一起值连接.

如果某人有对它的引用或对它的引用(例如,对一个struct或一个集合的元素的引用的引用),则借用一个值.借来的价值无法移动.

可变性(没有别名)

您可以随时在给定值中仅获取单个可变引用(&mut T),并且不会同时存在对该值的不可变引用 ; 它保证您可以独占访问这些内存,因此您可以安全地改变它.

别名(没有可变性)

您可以随时获取多个不可变引用(&T)到给定值.但是你不能通过这些引用(*)改变任何东西.

(*)我撒谎; 有些结构RefCell实现了"内部可变性"; 他们确实尊重Mutability XOR Aliasing原则,但将检查推迟到运行时.

而已?

几乎如此;)

为编译器编写器实现它已经相当复杂,并且可能会过度约束用户(一些安全的程序无法使用此系统证明是安全的,需要跳过箍),但核心原则实际上非常简单.

那剩下什么了?

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

  • @Myra:分段错误只是不安全内存访问的症状之一.由于这里解释的机制,Rust是内存安全的,因此没有分段错误,因为它没有内存损坏. (2认同)
  • 你的回答和大多数 Rust 宣传似乎只关注“临时”内存安全,即防止双重释放和释放后使用,Rust 确实有一个有趣的解决方案。那么*空间*内存安全呢?如何防止越界内存访问? (2认同)
  • 动态边界检查在这里作为答案是有意义的,但这不是“几乎任何其他语言”所做的。像 C/C++ 这样的内存不安全语言不会进行这些检查,而程序员将面临危险。鉴于空间记忆安全对于安全性与时间记忆安全同样重要,我建议更新您的答案以反映这一现实,而不是听起来好像时间记忆安全是“全部”。我相信 Rust 足够棒了,它不需要宣传来默默地重新定义诸如“内存安全”之类的一般概念,只意味着“临时内存安全”。 (2认同)