Module core::prim_pointer
1.0.0 · source · Expand description
Raw, unsafe pointers, *const T, and *mut T.
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.
Storing through a raw pointer using *ptr = data calls drop on the old value, so
write must be used if the type has drop glue and memory is not already
initialized - otherwise drop would be called on the uninitialized memory.
Use the null and null_mut functions to create null pointers, and the
is_null method of the *const T and *mut T types to check for null.
The *const T and *mut T types also define the offset method, for
pointer math.
Common ways to create raw pointers
1. Coerce a reference (&T) or mutable reference (&mut T).
let my_num: i32 = 10;
let my_num_ptr: *const i32 = &my_num;
let mut my_speed: i32 = 88;
let my_speed_ptr: *mut i32 = &mut my_speed;RunTo get a pointer to a boxed value, dereference the box:
let my_num: Box<i32> = Box::new(10);
let my_num_ptr: *const i32 = &*my_num;
let mut my_speed: Box<i32> = Box::new(88);
let my_speed_ptr: *mut i32 = &mut *my_speed;RunThis does not take ownership of the original allocation and requires no resource management later, but you must not use the pointer after its lifetime.
2. Consume a box (Box<T>).
The into_raw function consumes a box and returns
the raw pointer. It doesn’t destroy T or deallocate any memory.
let my_speed: Box<i32> = Box::new(88);
let my_speed: *mut i32 = Box::into_raw(my_speed);
// By taking ownership of the original `Box<T>` though
// we are obligated to put it together later to be destroyed.
unsafe {
drop(Box::from_raw(my_speed));
}RunNote that here the call to drop is for clarity - it indicates
that we are done with the given value and it should be destroyed.
3. Create it using ptr::addr_of!
Instead of coercing a reference to a raw pointer, you can use the macros
ptr::addr_of! (for *const T) and ptr::addr_of_mut! (for *mut T).
These macros allow you to create raw pointers to fields to which you cannot
create a reference (without causing undefined behaviour), such as an
unaligned field. This might be necessary if packed structs or uninitialized
memory is involved.
#[derive(Debug, Default, Copy, Clone)]
#[repr(C, packed)]
struct S {
aligned: u8,
unaligned: u32,
}
let s = S::default();
let p = std::ptr::addr_of!(s.unaligned); // not allowed with coercionRun4. Get it from C.
#[allow(unused_extern_crates)]
extern crate libc;
use std::mem;
unsafe {
let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>()) as *mut i32;
if my_num.is_null() {
panic!("failed to allocate memory");
}
libc::free(my_num as *mut libc::c_void);
}RunUsually you wouldn’t literally use malloc and free from Rust,
but C APIs hand out a lot of pointers generally, so are a common source
of raw pointers in Rust.