Primitive Type pointer [-] [+]

Operations on unsafe pointers, *const T, and *mut T.

Working with unsafe pointers in Rust is uncommon, typically limited to a few patterns.

Use the null function to create null pointers, and the is_null method of the *const T type to check for null. The *const T type also defines the offset method, for pointer math.

Common ways to create unsafe pointers

1. Coerce a reference (&T) or mutable reference (&mut T).

fn main() { 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; }
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;

To get a pointer to a boxed value, dereference the box:

fn main() { 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; }
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;

This 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.

#![feature(alloc)] extern crate std; fn main() { use std::boxed; unsafe { let my_speed: Box<i32> = Box::new(88); let my_speed: *mut i32 = boxed::into_raw(my_speed); // By taking ownership of the original `Box<T>` though // we are obligated to put it together later to be destroyed. drop(Box::from_raw(my_speed)); } }
use std::boxed;

unsafe {
    let my_speed: Box<i32> = Box::new(88);
    let my_speed: *mut i32 = boxed::into_raw(my_speed);

    // By taking ownership of the original `Box<T>` though
    // we are obligated to put it together later to be destroyed.
    drop(Box::from_raw(my_speed));
}

Note 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. Get it from C.

#![feature(libc)] extern crate libc; use std::mem; fn main() { unsafe { let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut i32; if my_num.is_null() { panic!("failed to allocate memory"); } libc::free(my_num as *mut libc::c_void); } }
extern crate libc;

use std::mem;

fn main() {
    unsafe {
        let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>() as libc::size_t) as *mut i32;
        if my_num.is_null() {
            panic!("failed to allocate memory");
        }
        libc::free(my_num as *mut libc::c_void);
    }
}

Usually 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 unsafe pointers in Rust.

Methods

impl<T> *const T where T: ?Sized

fn is_null(self) -> bool

Returns true if the pointer is null.

unsafe fn as_ref(&self) -> Option<&'a T>

Unstable

: Option is not clearly the right return type, and we may want to tie the return lifetime to a borrow of the raw pointer

Returns None if the pointer is null, or else returns a reference to the value wrapped in Some.

Safety

While this method and its mutable counterpart are useful for null-safety, it is important to note that this is still an unsafe operation because the returned value could be pointing to invalid memory.

unsafe fn offset(self, count: isize) -> *const T

Calculates the offset from a pointer. count is in units of T; e.g. a count of 3 represents a pointer offset of 3 * sizeof::<T>() bytes.

Safety

The offset must be in-bounds of the object, or one-byte-past-the-end. Otherwise offset invokes Undefined Behaviour, regardless of whether the pointer is used.

impl<T> *mut T where T: ?Sized

fn is_null(self) -> bool

Returns true if the pointer is null.

unsafe fn as_ref(&self) -> Option<&'a T>

Unstable

: Option is not clearly the right return type, and we may want to tie the return lifetime to a borrow of the raw pointer

Returns None if the pointer is null, or else returns a reference to the value wrapped in Some.

Safety

While this method and its mutable counterpart are useful for null-safety, it is important to note that this is still an unsafe operation because the returned value could be pointing to invalid memory.

unsafe fn offset(self, count: isize) -> *mut T

Calculates the offset from a pointer. count is in units of T; e.g. a count of 3 represents a pointer offset of 3 * sizeof::<T>() bytes.

Safety

The offset must be in-bounds of the object, or one-byte-past-the-end. Otherwise offset invokes Undefined Behaviour, regardless of whether the pointer is used.

unsafe fn as_mut(&self) -> Option<&'a mut T>

Unstable

: return value does not necessarily convey all possible information

Returns None if the pointer is null, or else returns a mutable reference to the value wrapped in Some.

Safety

As with as_ref, this is unsafe because it cannot verify the validity of the returned pointer.

Trait Implementations

impl<T> Zeroable for *const T where T: ?Sized

impl<T> Zeroable for *mut T where T: ?Sized

impl<T> PartialEq<*const T> for *const T where T: ?Sized

fn eq(&self, other: &*const T) -> bool

fn ne(&self, other: &Rhs) -> bool

impl<T> Eq for *const T where T: ?Sized

impl<T> PartialEq<*mut T> for *mut T where T: ?Sized

fn eq(&self, other: &*mut T) -> bool

fn ne(&self, other: &Rhs) -> bool

impl<T> Eq for *mut T where T: ?Sized

impl<T> Clone for *const T where T: ?Sized

fn clone(&self) -> *const T

fn clone_from(&mut self, source: &Self)

impl<T> Clone for *mut T where T: ?Sized

fn clone(&self) -> *mut T

fn clone_from(&mut self, source: &Self)

impl<T> Ord for *const T where T: ?Sized

fn cmp(&self, other: &*const T) -> Ordering

impl<T> PartialOrd<*const T> for *const T where T: ?Sized

fn partial_cmp(&self, other: &*const T) -> Option<Ordering>

fn lt(&self, other: &*const T) -> bool

fn le(&self, other: &*const T) -> bool

fn gt(&self, other: &*const T) -> bool

fn ge(&self, other: &*const T) -> bool

impl<T> Ord for *mut T where T: ?Sized

fn cmp(&self, other: &*mut T) -> Ordering

impl<T> PartialOrd<*mut T> for *mut T where T: ?Sized

fn partial_cmp(&self, other: &*mut T) -> Option<Ordering>

fn lt(&self, other: &*mut T) -> bool

fn le(&self, other: &*mut T) -> bool

fn gt(&self, other: &*mut T) -> bool

fn ge(&self, other: &*mut T) -> bool

impl<T> !Send for *const T

impl<T> !Send for *mut T

impl<T> !Sync for *const T

impl<T> !Sync for *mut T

impl<T> Hash for *const T

fn hash<H>(&self, state: &mut H) where H: Hasher

fn hash_slice<H>(data: &[Self], state: &mut H) where H: Hasher

impl<T> Hash for *mut T

fn hash<H>(&self, state: &mut H) where H: Hasher

fn hash_slice<H>(data: &[Self], state: &mut H) where H: Hasher

impl<T> Pointer for *const T

fn fmt(&self, f: &mut Formatter) -> Result<(), Error>

impl<T> Pointer for *mut T

fn fmt(&self, f: &mut Formatter) -> Result<(), Error>

impl<T> Debug for *const T

fn fmt(&self, f: &mut Formatter) -> Result<(), Error>

impl<T> Debug for *mut T

fn fmt(&self, f: &mut Formatter) -> Result<(), Error>