Rust has a number of different smart pointer types in its standard library, but there are two types that are extra-special. Much of Rust’s safety comes from compile-time checks, but raw pointers don’t have such guarantees, and are unsafe to use.
*const T
`*const Tand
` and *mut T
`*mut Tare called ‘raw pointers’ in Rust. Sometimes, when writing certain kinds of libraries, you’ll need to get around Rust’s safety guarantees for some reason. In this case, you can use raw pointers to implement your library, while exposing a safe interface for your users. For example,
` are called ‘raw pointers’ in Rust. Sometimes, when
writing certain kinds of libraries, you’ll need to get around Rust’s safety
guarantees for some reason. In this case, you can use raw pointers to implement
your library, while exposing a safe interface for your users. For example, *
`*pointers are allowed to alias, allowing them to be used to write shared-ownership types, and even thread-safe shared memory types (the
`
pointers are allowed to alias, allowing them to be used to write
shared-ownership types, and even thread-safe shared memory types (the Rc<T>
`Rcand
`
and Arc<T>
`Arc
Here are some things to remember about raw pointers that are different than other pointer types. They:
Box
`Boxand
` and &
`&`);Box
`Box`, and so require
manual resource management;Box
`Box`, hence the Rust compiler cannot protect against bugs like
use-after-free;&
`&`, and so the compiler cannot
reason about dangling pointers; and*const T
`*const T`.Creating a raw pointer is perfectly safe:
fn main() { let x = 5; let raw = &x as *const i32; let mut y = 10; let raw_mut = &mut y as *mut i32; }let x = 5; let raw = &x as *const i32; let mut y = 10; let raw_mut = &mut y as *mut i32;
However, dereferencing one is not. This won’t work:
fn main() { let x = 5; let raw = &x as *const i32; println!("raw points at {}", *raw); }let x = 5; let raw = &x as *const i32; println!("raw points at {}", *raw);
It gives this error:
error: dereference of unsafe pointer requires unsafe function or block [E0133]
println!("raw points at{}", *raw);
^~~~
When you dereference a raw pointer, you’re taking responsibility that it’s not
pointing somewhere that would be incorrect. As such, you need unsafe
`unsafe`:
let x = 5; let raw = &x as *const i32; let points_at = unsafe { *raw }; println!("raw points at {}", points_at);
For more operations on raw pointers, see their API documentation.
Raw pointers are useful for FFI: Rust’s *const T
`*const Tand
` and *mut T
`*mut Tare similar to C’s
` are similar to
C’s const T*
`const T*and
` and T*
`T*`, respectfully. For more about this use, consult the
FFI chapter.
At runtime, a raw pointer *
`*and a reference pointing to the same piece of data have an identical representation. In fact, an
` and a reference pointing to the same piece of
data have an identical representation. In fact, an &T
`&Treference will implicitly coerce to an
` reference will
implicitly coerce to an *const T
`*const Traw pointer in safe code and similarly for the
` raw pointer in safe code and similarly for
the mut
`mutvariants (both coercions can be performed explicitly with, respectively,
` variants (both coercions can be performed explicitly with,
respectively, value as *const T
`value as *const Tand
` and value as *mut T
`value as *mut T`).
Going the opposite direction, from *const
`*constto a reference
` to a reference &
`&, is not safe. A
`, is not safe. A
&T
`&Tis always valid, and so, at a minimum, the raw pointer
` is always valid, and so, at a minimum, the raw pointer *const T
`*const Thas to point to a valid instance of type
` has to
point to a valid instance of type T
`T`. Furthermore, the resulting pointer must
satisfy the aliasing and mutability laws of references. The compiler assumes
these properties are true for any references, no matter how they are created,
and so any conversion from raw pointers is asserting that they hold. The
programmer must guarantee this.
The recommended method for the conversion is
fn main() { let i: u32 = 1; // explicit cast let p_imm: *const u32 = &i as *const u32; let mut m: u32 = 2; // implicit coercion let p_mut: *mut u32 = &mut m; unsafe { let ref_imm: &u32 = &*p_imm; let ref_mut: &mut u32 = &mut *p_mut; } }let i: u32 = 1; // explicit cast let p_imm: *const u32 = &i as *const u32; let mut m: u32 = 2; // implicit coercion let p_mut: *mut u32 = &mut m; unsafe { let ref_imm: &u32 = &*p_imm; let ref_mut: &mut u32 = &mut *p_mut; }
The &*x
`&*xdereferencing style is preferred to using a
` dereferencing style is preferred to using a transmute
`transmute. The latter is far more powerful than necessary, and the more restricted operation is harder to use incorrectly; for example, it requires that
`. The latter
is far more powerful than necessary, and the more restricted operation is
harder to use incorrectly; for example, it requires that x
`xis a pointer (unlike
` is a pointer
(unlike transmute
`transmute`).