Function std::ptr::write

1.0.0 (const: unstable) · source ·
pub unsafe fn write<T>(dst: *mut T, src: T)
Expand description

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

write 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 from.

§Safety

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

  • dst must be valid for writes.

  • dst must be properly aligned. Use write_unaligned if this is not the case.

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

§Examples

Basic usage:

let mut x = 0;
let y = &mut x as *mut i32;
let z = 12;

unsafe {
    std::ptr::write(y, z);
    assert_eq!(std::ptr::read(y), 12);
}
Run

Manually implement mem::swap:

use std::ptr;

fn swap<T>(a: &mut T, b: &mut T) {
    unsafe {
        // Create a bitwise copy of the value at `a` in `tmp`.
        let tmp = ptr::read(a);

        // Exiting at this point (either by explicitly returning or by
        // calling a function which panics) would cause the value in `tmp` to
        // be dropped while the same value is still referenced by `a`. This
        // could trigger undefined behavior if `T` is not `Copy`.

        // Create a bitwise copy of the value at `b` in `a`.
        // This is safe because mutable references cannot alias.
        ptr::copy_nonoverlapping(b, a, 1);

        // As above, exiting here could trigger undefined behavior because
        // the same value is referenced by `a` and `b`.

        // Move `tmp` into `b`.
        ptr::write(b, tmp);

        // `tmp` has been moved (`write` takes ownership of its second argument),
        // so nothing is dropped implicitly here.
    }
}

let mut foo = "foo".to_owned();
let mut bar = "bar".to_owned();

swap(&mut foo, &mut bar);

assert_eq!(foo, "bar");
assert_eq!(bar, "foo");
Run