Function std::slice::from_raw_parts
1.0.0 (const: 1.64.0) · source · pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
Expand description
根据指针和长度形成切片。
len
参数是 元素 的数量,而不是字节数。
Safety
如果违反以下任一条件,则行为是未定义的:
-
对于
len * mem::size_of::<T>()
多个字节的读取,data
必须是 valid,并且必须正确对齐。这尤其意味着:- 该切片的整个存储范围必须包含在一个分配的对象中! 切片永远不能跨越多个分配的对象。请参见 下文 了解一个没有考虑到这一点的错误示例。
- 即使对于零长度切片,
data
也必须非空且对齐。 这样做的一个原因是,枚举布局优化可能依赖于对齐的引用 (包括任何长度的切片) 和非空值,以将它们与其他数据区分开。 您可以使用NonNull::dangling()
获得可用作零长度切片的data
的指针。
-
data
必须指向len
类型的T
类型的连续正确初始化值。 -
返回的切片引用的内存在生命周期
'a
期间不得更改,除非在UnsafeCell
内部。 -
切片的总大小
len * mem::size_of::<T>()
必须不大于isize::MAX
。 请参见pointer::offset
的安全文档。
Caveat
从使用中可以推断出返回切片的生命周期。 为防止意外滥用,建议将生命周期与生命周期中任何安全的来源联系起来,例如通过提供一个辅助函数,获取切片的宿主值的生命周期,或通过明确的注解法。
Examples
use std::slice;
// 显示单个元素的切片
let x = 42;
let ptr = &x as *const _;
let slice = unsafe { slice::from_raw_parts(ptr, 1) };
assert_eq!(slice[0], 42);
Run用法不正确
下面的 join_slices
函数是不健全的 ⚠️
use std::slice;
fn join_slices<'a, T>(fst: &'a [T], snd: &'a [T]) -> &'a [T] {
let fst_end = fst.as_ptr().wrapping_add(fst.len());
let snd_start = snd.as_ptr();
assert_eq!(fst_end, snd_start, "Slices must be contiguous!");
unsafe {
// 上面的断言确保 `fst` 和 `snd` 是连续的,但是它们仍可能包含在 _different allocated objects_ 中,在这种情况下,创建此切片是未定义的行为。
slice::from_raw_parts(fst.as_ptr(), fst.len() + snd.len())
}
}
fn main() {
// `a` 和 `b` 是不同的分配对象...
let a = 42;
let b = 27;
// ... 尽管如此,它仍然可以在内存中连续布局: | 一个 | b |
let _ = join_slices(slice::from_ref(&a), slice::from_ref(&b)); // UB
}
Run