Function core::intrinsics::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