2016-03-21 2 views
8

Я искал язык для изучения, и я увидел, что Rust становится довольно популярным.Как Rust гарантирует безопасность памяти и предотвращает segfaults?

Две вещи произвели на меня впечатление о Rust, безопасности памяти и предотвращении segfaults.

Как достигается ржавчина? Какие различия между Rust и Java, например, позволяют использовать функции безопасности Rust?

+0

Java также гарантирует безопасность памяти и предотвращает segfault (через свой VM + Garbage Collector), поэтому какая разница между Java и Rust вы ищете? Кроме того, прочитали ли вы [книгу ржавчины] (https://doc.rust-lang.org/book/)? (он может не отвечать на ваши вопросы). Кроме того, вы читаете http://stackoverflow.com/questions/29628650/how-does-rust-achieve-compile-time-only-pointer-safety? –

+0

Java использует трассировочный сборщик мусора, который сохраняет все объекты в живых, кроме тех, которые предположительно недостижимы (и, следовательно, их отсутствие ненаблюдаемо). Rust использует систему аффинного типа, которая гарантирует, что каждый объект имеет четко определенное время жизни и правила, запрещающие принимать ссылки, которые могут выжить за время жизни объекта-референта. –

+0

Насколько я знаю, Java не гарантирует безопасность памяти. – ferit

ответ

16

Насколько 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++ (до смарт-указатели).

заимствование

Освещенность, что исходит от ржавчины, что проблемы с памятью возникают, когда один перемешивает ступенчатость и переменчивость: то есть, когда одна часть памяти доступна по нескольким путям и мутируют (или перемещен), оставив после себя болтающиеся указатели.

Таким образом, основной принцип проверки займа: Mutability XOR Aliasing. В принципе это похоже на блокировку чтения-записи.

Это означает, что компилятор ржавчина отслеживает наложения спектров информации, для которой он использует прижизненных аннотации (те 'a в &'a var) для подключения жизни ссылок и значения они относятся к вместе.

Значение заимствовано, если у кого-то есть ссылка на него или INTO (например, ссылка на поле struct или на элемент коллекции). Заимствованное значение не может быть перемещено.

Изменчивости (без наложения спектров)

Вы можете получить только один изменяемого ссылка (&mut T) в заданном значение в любое время, и неизменная ссылка в это значение не может существовать не в том же самом время; он гарантирует, что у вас есть эксклюзивный доступ к этому лакомый кусочек памяти, и вы можете спокойно его мутировать.

Aliasing (без изменчивости)

Вы можете получить несколько неизменных ссылок (&T) в заданном значение в любое время.Однако вы не можете мутировать ничего через эти ссылки (*).

(*) Я лгу; существуют такие структуры, как RefCell, которые реализуют «внутреннюю изменчивость»; они уважают принцип Mutability XOR Aliasing, но вместо этого откладывают проверку на время выполнения.

Это все?

Почти так;)

Это уже довольно сложно реализовать для компилятора писателей, и может чрезмерно ограничивать пользователей (некоторые программы, которые были бы безопасны, не может быть доказана безопасность использования этой системы, требуя, чтобы перейти через обручи), однако основные принципы действительно настолько просты.

Так что же осталось?

Оценка границ. Это не ракетостроение, но, тем не менее, может привести к снижению производительности. Большинство языков имеют некоторую степень поддержки, C - большое исключение, а C++ имеет , но он не является обязательным.

+0

Спасибо за ответ. Хотели бы вы добавить что-то о предотвращении segfault? – Myra

+1

@Myra: Ошибка сегментации - это лишь один из признаков небезопасного доступа к памяти. Ржавчина является надежной памятью, благодаря объясненному здесь механизму и, следовательно, так же свободна от атак сегментации, что и без повреждения памяти. –

+1

@Myra С ржавчиной только segfault, которую вы легко можете спровоцировать, это «переполнение стека». Любые другие segfaults означают, что есть ошибка в компиляторе или в библиотеках, которые используют небезопасный код (и библиотеки C через ffi). – qthree