Почему нет segfault при доступе к переменной, которая вышла из области видимости с использованием небезопасного Rust? - PullRequest
0 голосов
/ 19 декабря 2018

Я столкнулся с этим странным явлением, играя с небезопасным Rust.Я думаю, что этот код должен сделать ошибку сегментации, но это не так.Я что-то пропустил?Я попытался установить указатель на переменную с более коротким временем жизни, а затем разыменовать его.

// function that sets a pointer to a variable with a shorter lifetime
unsafe fn what(p: &mut *const i32) {
    let a = 2;
    *p = &a;
    //let addr = *p;    // I will talk about this later
    println!("inside: {}", **p);
}

fn main() {
    let mut p: *const i32 = 0 as *const i32;
    unsafe {
        what(&mut p);

        // I thought this line would make a segfault because 'a' goes out of scope at the end of the function making the address invalid
        println!("segfault? {}", *p);

        // Even more unsettling: I can increment the address and still dereference it.
        p = ((p as usize) + 1) as *const i32;
        println!("I'm definitely missing something: {}", *p);
    }
}

Эта программа выводит:

inside: 2
segfault? {random number around 20000. probably uninitialized memory but why?}
I'm definitely missing something: {uninitialized memory}

Если я раскомментирую строку

let addr = *p;

второй ряд становится

segfault? 2

Почему нет segfault?Может ли компилятор продлить срок службы a или адрес p указывает на безопасность?Я скучаю по основной информации об указателях в Rust?

1 Ответ

0 голосов
/ 20 декабря 2018

Это не уникально для Rust.См .:

TL; DR: у вас есть ложь компилятор.Ваш unsafe блок не соответствует требованиям безопасного кода.Это означает, что вы создали неопределенное поведение и программе разрешено делать все, что она хочет.Это может означать:

Сегфоулты никогда гарантированный результат. ошибка сегментации возникает, когда вы обращаетесь к памяти, которая находится за пределами фрагмента памяти вашего потока / процесса.Память стека находится внутри этого чанка, поэтому вряд ли будет запускать регистр.

См. Также:

...