wasmer_types::lib::std::ptr

Function read

1.0.0 (const: 1.71.0) · Source
pub const unsafe fn read<T>(src: *const T) -> T
Available on crate feature std only.
Expand description

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

§Safety

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

  • src must be valid for reads.

  • src must be properly aligned. Use read_unaligned if this is not the case.

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

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

§Examples

Basic usage:

let x = 12;
let y = &x as *const i32;

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

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");

§Ownership of the Returned Value

read 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 assigning to *src counts as a use because it will attempt to drop the value at *src.

write() can be used to overwrite data without causing it to be dropped.

use std::ptr;

let mut s = String::from("foo");
unsafe {
    // `s2` now points to the same underlying memory as `s`.
    let mut s2: String = ptr::read(&s);

    assert_eq!(s2, "foo");

    // Assigning to `s2` causes its original value to be dropped. Beyond
    // this point, `s` must no longer be used, as the underlying memory has
    // been freed.
    s2 = String::default();
    assert_eq!(s2, "");

    // Assigning to `s` would cause the old value to be dropped again,
    // resulting in undefined behavior.
    // s = String::from("bar"); // ERROR

    // `ptr::write` can be used to overwrite a value without dropping it.
    ptr::write(&mut s, String::from("bar"));
}

assert_eq!(s, "bar");