Function core::intrinsics::copy_nonoverlapping1.0.0[][src]

pub 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,但是交换了参数顺序。

Safety

如果违反以下任一条件,则行为是未定义的:

  • src 对于 count * size_of::<T>() 字节的读取,必须是 有效 的。

  • dst 对于 count * size_of::<T>() 字节的写入,必须为 有效 的。

  • srcdst 必须正确对齐。

  • src 开始的内存区域,大小为 count * size_of::<T> () 字节不得与以 dst 开始且大小相同的内存区域重叠。

read 一样,无论 T 是否为 Copycopy_nonoverlapping 都会创建 T 的按位副本。 如果 T 不是 Copy,则同时使用 bothviolate memory safety 开头的区域中的值都可以 violate memory safety

请注意,即使有效复制的大小 (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().offset(dst_len as isize);
        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