0
votes

I am stuck why the println on is *p1.offset(0) is giving me 0. Any ideas?

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);
        }
}

Here is the link to playground. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=18222645e5fa43cde787659402962be3

2

2 Answers

5
votes

Pointers do not own the things they point at, so when you do this:

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

the sequence of events that occurs is:

  • A Vec is constructed, with a buffer allocated on the heap
  • as_ptr() is called, returning a pointer to the buffer
  • The Vec is dropped, because there is nothing owning it, so the buffer is deallocated
  • When you later dereference the pointer, you are invoking Undefined Behavior

The second case works correctly:

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

because "123" is a string literal, and string literals have 'static lifetime - they last as long as the program itself.

0
votes

Here is a working version.

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);
        }
}

I don't know why need to extract vec to separate variable