pointers-slices-safety
指针与切片安全边界(offset/add/wrapping 与 from_raw_parts 不变量)
指针算术与边界
ptr.add(n)
/ptr.sub(n)
:以元素为单位偏移,不允许越过分配边界(allocation),溢出 UB。ptr.offset(n)
:允许负偏移,需更谨慎;新代码优先add/sub
。wrapping_add/sub
:在机器整数上环绕,但仍必须保持 provenance 和在同一 allocation 内的约束。- “one-past-end” 仅对原始指针在比较/再偏移时合法;引用不允许指向越界位置。
from_raw_parts 的不变量
// SAFETY: 调用者必须保证:
// 1) ptr 源自同一分配(provenance)且对齐满足 T 的对齐要求
// 2) len 元素均已初始化(读取未初始化内存是 UB)
// 3) 内存不在切片存活期间被释放/收回
// 4) 对于 &mut [T],还需独占访问(无别名可变)
use std::slice;
use std::mem::MaybeUninit;
unsafe fn view_initialized(ptr: *const u32, len: usize) -> &'static [u32] {
slice::from_raw_parts(ptr, len)
}
// 对于部分初始化的缓冲区,先用 MaybeUninit 再安全转换:
unsafe fn assume_init_slice(buf: &[MaybeUninit<u32>]) -> &[u32] {
// 保证前 n 项已初始化
MaybeUninit::slice_assume_init_ref(buf)
}