在运行时在堆上分配缓冲区

sem*_*xzv 1 heap memory-management ownership rust

我正在通过编写简单的二进制解码器来学习 Rust。

我正在使用BufferedReader带有byteorder crate 的 a来读取数字,但是我在读取字节缓冲区时遇到了问题。

我想将字节数据读入在运行时分配的缓冲区中。然后我想将此缓冲区的所有权传递给一个结构。当 struct 不再使用时,应释放缓冲区。

除了一些Vec::with_capacity()hacks之外,似乎没有办法在堆上分配运行时确定的大小的数组。任何想法如何使用适当的 Rust 语义来实现它?

Dav*_*vid 6

这将创建一个预先分配的可变 500MB 字节缓冲区存储在堆上,不需要不安全的锈:

// 正确的

let mut buffer = vec![0_u8; 536870912];
Run Code Online (Sandbox Code Playgroud)

请注意,下面的代码不是一个好主意,很可能会导致堆栈溢出,因为缓冲区是在装箱并移动到堆之前在堆栈上创建的。

// 不正确 - 使用的堆栈

let mut bytes: Box<[u8]> = Box::new([0_u8; 536870912])
Run Code Online (Sandbox Code Playgroud)

// 不正确 - 慢

let mut bytes = Vec::with_capacity(536870912);
for _ in 0..bytes.capacity() {
    bytes.push(0_u8);
}
Run Code Online (Sandbox Code Playgroud)


Mat*_* M. 5

Rust 是一种低级语言;因此你可以分配原始内存,然后自己用对象填充它。当然,它需要unsafe代码,就像所有摆弄原始内存一样。

这是一个完整的示例

use std::{
    alloc::{self, Layout},
    mem, ptr,
};

fn main() {
    unsafe {
        let layout = Layout::from_size_align(512 * 1024, 4 * 1024).expect("Invalid layout");
        let mut raw: *mut i32 = mem::transmute(alloc::alloc(layout));

        for i in 0..(512 * 1024 / 4) {
            ptr::write(raw, i as i32);
            raw = raw.offset(1)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,在实际代码中,我只是用来Vec为我安全地管理内存。只是更简单!