Module std::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 coercion
Run4. 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.