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

时间:2015-09-05 15:08:20

标签: memory-management heap rust ownership

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

我正在使用BufferedReaderbyteorder crate来读取数字,但是我在读取字节缓冲区方面遇到了问题。

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

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

3 个答案:

答案 0 :(得分:3)

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

//正确

let mut buffer = vec![0_u8; 536870912];

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

//不正确-已使用堆栈

let mut bytes: Box<[u8]> = Box::new([0_u8; 536870912])

//不正确-慢

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

答案 1 :(得分:2)

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

以下是a complete example

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)
        }
    }
}

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

答案 2 :(得分:0)

  

我尝试使用box,但似乎它是实验性的,我不能将它与发布分支一起使用。任何想法如何用适当的Rust语义实现它?

The Rust Programming Language ,特别是“The Stack and the Heap”一节中介绍了这一点。

使用Box::new

fn main() {
    let answer: Box<u8> = Box::new(42);
}