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

时间:2016-03-21 16:11:54

标签: memory-management segmentation-fault rust

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

有两件事让我印象深刻的是Rust,内存安全和防止段错误。

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

1 个答案:

答案 0 :(得分:19)

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

<强>所有权

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

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 ++中经常遇到的可怕的双重(在智能指针之前)。

<强>借款

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

借用检查的核心原则是:可变性XOR别名。原则上它类似于读写锁。

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

如果某人有引用它或INTO它(例如,对struct的字段或对集合的元素的引用),则借用该值。借来的价值无法移动。

可变性(没有别名)

您可以随时在给定值中只获取一个可变引用&mut T),并且此值中不存在不可变引用同一时间;它保证您可以独占访问这些内存,因此您可以安全地改变它。

别名(没有可变性)

您可以随时将多个不可变引用&T)添加到给定值中。但是,你不能通过这些引用(*)来改变任何东西。

(*)我撒谎;像RefCell这样的结构实现了“内部可变性”;他们确实尊重Mutability XOR Aliasing原则,但将检查推迟到运行时。

就是这样?

差不多;)

为编译器编写器实现它已经相当复杂,并且可能会过度约束用户(某些安全的程序无法通过此系统证明是安全的,需要跳过箍),但核心原则确实如此就这么简单。

那剩下什么了?

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