Macro std::ptr::addr_of_mut

1.51.0 · source ·
pub macro addr_of_mut($place:expr) {
    ...
}
Expand description

创建一个 mut 裸指针到一个位置,而无需创建中间引用。

仅当指针正确对齐并指向初始化数据时,才允许使用 &/&mut 创建引用。 对于那些不满足要求的情况,应改用裸指针。 但是,&mut expr as *mut _ 在将其强制转换为裸指针之前会创建一个引用,并且该引用与所有其他引用都遵循相同的规则。

该宏可以创建一个裸指针,而无需先创建一个引用。

但请注意,addr_of_mut!(expr) 中的 expr 仍受所有常规规则的约束。 特别是,addr_of_mut!(*ptr::null_mut()) 是未定义行为,因为它解引用空指针。

Examples

创建指向未对齐数据的指针:

use std::ptr;

#[repr(packed)]
struct Packed {
    f1: u8,
    f2: u16,
}

let mut packed = Packed { f1: 1, f2: 2 };
// `&mut packed.f2` 会创建一个未对齐的引用,因此是未定义的行为!
let raw_f2 = ptr::addr_of_mut!(packed.f2);
unsafe { raw_f2.write_unaligned(42); }
assert_eq!({packed.f2}, 42); // `{...}` 强制复制字段而不是创建引用。
Run

创建指向未初始化数据的指针:

use std::{ptr, mem::MaybeUninit};

struct Demo {
    field: bool,
}

let mut uninit = MaybeUninit::<Demo>::uninit();
// `&uninit.as_mut().field` 会创建一个对未初始化的 `bool` 的引用,因此是未定义的行为!
let f1_ptr = unsafe { ptr::addr_of_mut!((*uninit.as_mut_ptr()).field) };
unsafe { f1_ptr.write(true); }
let init = unsafe { uninit.assume_init() };
Run