寻找 C memcpy 等效项

Ant*_*REL 9 rust

将字节从 src 写入 dst 的最有效(不安全)方法

我发现copy_nonoverlapping

pub unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize)
将 count * size_of::() 个字节从 src 复制到 dst。源和目的地不得重叠

我要写入的数据位于bufat index 4,我想将其写入_bytes_buffat (variable) index index * MAX_DATA_LENGTHMAX_DATA_LENGTH约为64Kb。

不过,我在让它发挥作用时遇到了一些麻烦。请参阅以下我当前尝试正确编写它的片段:

let mut  _bytes_buf:Vec<u8>; // big buffer, we don't know the total size at compilation
let mut buf = [0u8; MAX_DATA_LENGTH]; // small buffer

// [...] we now know the size, I write '3' below to make it simple

let len:usize = MAX_DATA_LENGTH * 3 as usize;
_bytes_buf = Vec::with_capacity(len); // any difference with !vec[0; len] ?
unsafe { _bytes_buf.set_len(len); }

// [...] each time buf has a different content and index is either 0, 1 or 2.

unsafe {
    let dst_ptr = &_bytes_buf[index * MAX_DATA_LENGTH].offset(MAX_DATA_LENGTH as isize); 
    let src_ptr = &buf[4];
    ptr::copy_nonoverlapping(src_ptr, dst_ptr, MAX_DATA_LENGTH);
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能让它工作(最后一个不安全的块)?我找到了很多信息,但有些信息已被弃用或过时,因此我正在寻找截至 2021 年的方法。

另外,如果这不是最佳方法(copy_nonoverlapping),我将非常感激了解更多关于我应该如何做的信息!

kmd*_*eko 12

Rust 的安全版本memcpy<[u8]>::copy_from_slice

const MAX_DATA_LENGTH: usize = 64000;

let mut bytes_buf = vec![0u8; MAX_DATA_LENGTH * 3];
let buf = [0u8; MAX_DATA_LENGTH];
let index = 0;

bytes_buf[index*MAX_DATA_LENGTH..(index+1)*MAX_DATA_LENGTH-4].copy_from_slice(&buf[4..]);
Run Code Online (Sandbox Code Playgroud)

如果您确实想要更直接的等价物,copy_nonoverlapping请按以下步骤操作:

unsafe {
    let dst_ptr = &mut bytes_buf[index*MAX_DATA_LENGTH] as *mut u8;
    let src_ptr = &buf[4] as *const u8;
    std::ptr::copy_nonoverlapping(src_ptr, dst_ptr, MAX_DATA_LENGTH-4);
}
Run Code Online (Sandbox Code Playgroud)

但是,除非必要,并且您了解确保安全unsafe所需的安全保证,否则请勿使用。

  • “我将使用不安全的,因为我已经知道大小”是每一个缓冲区溢出发生的方式......只是说。 (26认同)
  • 我强烈反对这样做,这可以防止您做出最终导致读取或写入超出范围的更改。例如,您帖子中的尝试在进行复制时没有考虑 4 字节标头。“copy_from_slice”方法可以捕捉到这一点,但“copy_nonoverlapping”方法则**不能**。您还一次复制 64kb,“if”不会对性能产生有意义的差异,因此需要使用“unsafe”。 (3认同)