Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer dereferencing in Rust

Tags:

rust

I am rather confused about the following problem. If I understand it correctly

let x = &42;

is expanded internally to

let x_value = 42;
let x = &x;

I think I have seen this in the Rust book somewhere but I cannot find the reference to it.

My problem is concerning the following code:

let x = 42;
let rx = &x;
let px = rx as *const i32 as *mut i32;
unsafe {
  *px = 0;
}
println!("{}", x);

As expected this prints 0. However, if I write

let rx = &42;
let px = rx as *const i32 as *mut i32;
unsafe {
  println!("Deref");
  *px = 0;
}
println!("{}", x);

the program terminates after printing out Deref. Aparently something goes wrong when px gets dereferenced. I guess my first assessment about let x = &42 getting expanded internally is wrong.

like image 839
jan Avatar asked Feb 26 '17 16:02

jan


People also ask

What is pointer dereferencing?

Dereferencing is used to access or manipulate data contained in memory location pointed to by a pointer. *(asterisk) is used with pointer variable when dereferencing the pointer variable, it refers to variable being pointed, so this is called dereferencing of pointers.

Can you use pointers in Rust?

Working with raw pointers in Rust is uncommon, typically limited to a few patterns. Raw pointers can be unaligned or null . However, when a raw pointer is dereferenced (using the * operator), it must be non-null and aligned.

Does Rust automatically dereference?

Rust will also insert automatic dereferencing as part of deref coercion. This is a special coercion that can only convert from one reference type to another. For example, this is what lets you convert from String to &str by writing &x instead of &*x .

What is reference and dereferencing?

The reference (&) and dereference operators (*) in Arduino are similar to C. Referencing and dereferencing are used with pointers. If x is a variable, then its address is represented by &x. Similarly, if p is a pointer, then the value contained in the address pointed to by p is represented by &p.


1 Answers

You're invoking undefined behavior. From the Rust Reference:

12.3 Behavior considered undefined

The following is a list of behavior which is forbidden in all Rust code, including within unsafe blocks and unsafe functions. [...]

  • Mutating non-mutable data (that is, data reached through a shared reference or data owned by a let binding), unless that data is contained within an UnsafeCell<U>.

Since you're mutating non-mutable data, you're invoking undefined behavior. The fact that it works at all in the first version is just (bad) luck.

like image 197
Cornstalks Avatar answered Nov 22 '22 13:11

Cornstalks