Почтение указателя Rust с векторами - PullRequest
0 голосов
/ 11 июля 2020

Я застрял, почему println на *p1.offset(0) дает мне 0. Есть идеи?

fn main() {
        let p1 : *const u8 = vec![17u8,2u8].as_ptr();
        let p2 : *const u8 = "123".as_ptr();
        
        unsafe{
        println!("{}", *p1.offset(0) as u8);//should get 17, but I get 0
        println!("{}", *p2.offset(0) as char);
        }
}

Вот ссылка на игровую площадку. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=18222645e5fa43cde787659402962be3

Ответы [ 2 ]

4 голосов
/ 11 июля 2020

Указатели не владеют тем, на что они указывают, поэтому, когда вы делаете это:

let p1 : *const u8 = vec![17u8,2u8].as_ptr();

последовательность событий, которая происходит, будет следующей:

  • A Vec is построенный, с буфером, выделенным в куче, вызывается
  • as_ptr(), возвращающий указатель на буфер
  • Vec отбрасывается, потому что ничто не владеет им, поэтому буфер освобождается
  • Когда вы позже разыменовываете указатель, вы вызываете Undefined Behavior

Второй случай работает правильно:

let p2 : *const u8 = "123".as_ptr();

потому что «123» - это строковый литерал и строковые литералы имеют 'static время жизни - они действуют столько же, сколько и сама программа.

0 голосов
/ 11 июля 2020

Вот рабочая версия.

fn main() {
        let data = vec![17u8,2u8];
        let p1 : *const u8 = data.as_ptr();
        let p2 : *const u8 = "123".as_ptr();
        
        unsafe{
        println!("{}", *p1.offset(0) as u8); // not get 17 instead of 0
        println!("{}", *p2.offset(0) as char);
        }
}

Не знаю, зачем нужно извлекать ve c в отдельную переменную

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...