Reputation: 139
I am learning Rust by writing simple binary decoder.
I'm using a BufferedReader
with the byteorder crate to read numbers, but I'm having problems with reading byte buffers.
I want to read byte data into buffer allocated at runtime. Then I want to pass ownership of this buffer to a struct. When struct is no longer in use, the buffer should be deallocated.
There seems to be no way to allocate array with size determined at runtime on heap except some Vec::with_capacity()
hacks. Any ideas how to implement this with proper Rust semantics?
Upvotes: 4
Views: 8001
Reputation: 432189
I tried using
box
but it seems that it is experimental and I can't use it with release branch. Any ideas how to implement this with proper Rust semantics?
This is covered in The Rust Programming Language, specifically the section "Using Box<T> to Point to Data on the Heap".
Use Box::new
:
fn main() {
let answer: Box<u8> = Box::new(42);
}
See also:
Upvotes: 0
Reputation: 300409
Rust is a low-level language; thus you can allocate raw memory and then fill it with objects yourself. Of course, it will require unsafe
code, as all fiddling with raw memory does.
Here is 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)
}
}
}
Of course, in real code, I would just use Vec
to safely manage the memory for me. It's just simpler!
Upvotes: 6
Reputation: 469
This will create a pre-allocated mutable 500MB byte buffer of zeros stored on the heap with no need for unsafe rust:
// Correct
let mut buffer = vec![0_u8; 536870912];
Note that the following code below is not a good idea and will most likely result in a stack overflow because the buffer is created on the stack before being boxed and moved to the heap.
// Incorrect - stack used
let mut bytes: Box<[u8]> = Box::new([0_u8; 536870912])
// Incorrect - slow
let mut bytes = Vec::with_capacity(536870912);
for _ in 0..bytes.capacity() {
bytes.push(0_u8);
}
Upvotes: 12