Function core::ptr::copy_nonoverlapping
1.0.0 (const: 1.63.0) · source · pub const unsafe fn copy_nonoverlapping<T>(
src: *const T,
dst: *mut T,
count: usize
)Expand description
将 count * size_of::<T>() 字节从 src 复制到 dst。源和目标必须不重叠。
对于可能重叠的内存区域,请改用 copy。
copy_nonoverlapping 在语义上等同于 C 的 memcpy,但交换了参数顺序。
副本是 “untyped”,因为数据可能未初始化或违反 T 的要求。初始化状态被完全保留。
Safety
如果违反以下任一条件,则行为是未定义的:
-
对于
count * size_of::<T>()字节的读取,src必须是 valid。 -
对于
count * size_of::<T>()字节的写入,dst必须是 valid。 -
src和dst必须正确对齐。 -
从
src开始的内存区域,大小为count * size_of::<T> ()字节不得与以dst开始且大小相同的内存区域重叠。
与 read 一样,无论 T 是否为 Copy,copy_nonoverlapping 都会创建 T 的按位副本。
如果 T 不是 Copy,则使用两个以 *src 开头的区域和以 *dst 开头的区域中的值可以 违反内存安全。
请注意,即使有效复制的大小 (count * size_of::<T>()) 是 0,指针也必须非空的并且正确对齐。
Examples
手动实现 Vec::append:
use std::ptr;
/// 将 `src` 的所有元素移到 `dst`,将 `src` 留空。
fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
let src_len = src.len();
let dst_len = dst.len();
// 确保 `dst` 具有足够的容量来容纳所有 `src`。
dst.reserve(src_len);
unsafe {
// 添加的调用总是安全的,因为 `Vec` 永远不会分配超过 `isize::MAX` 字节。
let dst_ptr = dst.as_mut_ptr().add(dst_len);
let src_ptr = src.as_ptr();
// 截断 `src` 而不丢弃其内容。
// 我们首先执行此操作,以避免在 panics 处出现问题时避免出现问题。
src.set_len(0);
// 这两个区域不能重叠,因为可变引用没有别名,并且两个不同的 vectors 不能拥有相同的内存。
ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
// 通知 `dst` 现在包含 `src` 的内容。
dst.set_len(dst_len + src_len);
}
}
let mut a = vec!['r'];
let mut b = vec!['u', 's', 't'];
append(&mut a, &mut b);
assert_eq!(a, &['r', 'u', 's', 't']);
assert!(b.is_empty());Run