# Function std::ptr::read_unaligned

1.17.0 (const: 1.71.0) · source ·

    pub const unsafe fn read_unaligned<T>(src: *const T) -> T

Expand description

Reads the value from `src` without moving it. This leaves the memory in `src` unchanged.

Unlike `read`, `read_unaligned` works with unaligned pointers.

## Safety

Behavior is undefined if any of the following conditions are violated:

- `src` must be valid for reads.

- `src` must point to a properly initialized value of type `T`.

Like `read`, `read_unaligned` creates a bitwise copy of `T`, regardless of whether `T` is `Copy`. If `T` is not `Copy`, using both the returned value and the value at `*src` can violate memory safety.

Note that even if `T` has size `0`, the pointer must be non-null.

### On `packed` structs

Attempting to create a raw pointer to an `unaligned` struct field with an expression such as `&packed.unaligned as *const FieldType` creates an intermediate unaligned reference before converting that to a raw pointer. That this reference is temporary and immediately cast is inconsequential as the compiler always expects references to be properly aligned. As a result, using `&packed.unaligned as *const FieldType` causes immediate undefined behavior in your program.

Instead you must use the `ptr::addr_of!` macro to create the pointer. You may use that returned pointer together with this function.

An example of what not to do and how this relates to `read_unaligned` is:

    #[repr(packed, C)]
    struct Packed {
        _padding: u8,
        unaligned: u32,
    }

    let packed = Packed {
        _padding: 0x00,
        unaligned: 0x01020304,
    };

    // Take the address of a 32-bit integer which is not aligned.
    // In contrast to `&packed.unaligned as *const _`, this has no undefined behavior.
    let unaligned = std::ptr::addr_of!(packed.unaligned);

    let v = unsafe { std::ptr::read_unaligned(unaligned) };
    assert_eq!(v, 0x01020304);

Run

Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however.

## Examples

Read a usize value from a byte buffer:

    use std::mem;

    fn read_usize(x: &[u8]) -> usize {
        assert!(x.len() >= mem::size_of::<usize>());

        let ptr = x.as_ptr() as *const usize;

        unsafe { ptr.read_unaligned() }
    }

Run