# Function std::ptr::write_unaligned

1.17.0 (const: unstable) · source ·

    pub unsafe fn write_unaligned<T>(dst: *mut T, src: T)

Expand description

Overwrites a memory location with the given value without reading or dropping the old value.

Unlike `write()`, the pointer may be unaligned.

`write_unaligned` does not drop the contents of `dst`. This is safe, but it could leak allocations or resources, so care should be taken not to overwrite an object that should be dropped.

Additionally, it does not drop `src`. Semantically, `src` is moved into the location pointed to by `dst`.

This is appropriate for initializing uninitialized memory, or overwriting memory that has previously been read with `read_unaligned`.

## Safety

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

- `dst` must be valid for writes.

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_mut!` macro to create the pointer. You may use that returned pointer together with this function.

An example of how to do it and how this relates to `write_unaligned` is:

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

    let mut packed: Packed = unsafe { std::mem::zeroed() };

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

    unsafe { std::ptr::write_unaligned(unaligned, 42) };

    assert_eq!({packed.unaligned}, 42); // `{...}` forces copying the field instead of creating a reference.

Run

Accessing unaligned fields directly with e.g. `packed.unaligned` is safe however (as can be seen in the `assert_eq!` above).

## Examples

Write a usize value to a byte buffer:

    use std::mem;

    fn write_usize(x: &mut [u8], val: usize) {
        assert!(x.len() >= mem::size_of::<usize>());

        let ptr = x.as_mut_ptr() as *mut usize;

        unsafe { ptr.write_unaligned(val) }
    }

Run