Malloc an array with Rust Layout

Viewed 940

My current code:

use std::alloc::{alloc, dealloc, Layout};

unsafe {
  let n = 0x10000; // I get this value from a function
  let layout = Layout::new::<[u8; n]>();// n is non-constant value issue E0435 E0425
  let mut ptr = alloc(layout);
  *(ptr as *mut u8) = 42;
}

What if I want to allocate 0x10000 of heap? I have read Layout documentation but I miss the example about allocating more than one u8. (Layout::new::<u8> works fine)

Is it the best way to allocate memory (unsafely) in Rust? Also what would be the best safe way to do it ?

Alternatively I have been using (which works very well):

let n = 0x10000;
let mut v<u8>; = Vec::with_capacity(n);
unsafe { v.set_len(n); }
1 Answers

To allocate a slice of size items of type T, you should just create a vector of them:

// resizable vector of 0x10000 items:
let vec: Vec<u8> = vec![0u8; 0x10000];

// unique pointer (Box) to a fixed-slice of 0x10000 items:
let boxed_slice: Box<[u8]> = vec![0u8; 0x10000].into_boxed_slice();

Note that this initialized each value of the array to 0, which is necessary because Rust generally expects values to be initialized (and uninitialized memory can lead to undefined behavior, even for integer types like u8).

Generally speaking, I'd also recommend that you avoid using std::mem::alloc directly in your code. When using it, you need to think more carefully about how you handle memory, there's more room for mistakes, and there are rarely any significant advantages over the safe variant above. Even if you want to allocate uninitialized memory and initialize it yourself, you're likely better off with Vec<MaybeUninit<T>> or Box<[MaybeUninit<T>], which provide a safer (but still unsafe) interface for uninitialized memory.

Related