There is already a question for this but related to Rust 0.13 and the syntax seems to have changed. From the current documentation I understood that creating an array on the heap would be something like this:
fn main() {
const SIZE: usize = 1024 * 1024;
Box::new([10.0; SIZE]);
}
But when I run this program I get the following error:
thread '<main>' has overflowed its stack
What am I doing wrong?
The problem is that the array is being passed to the Box::new
function as an argument, which means it has to be created first, which means it has to be created on the stack.
You're asking the compiler to create 8 megabytes of data on the stack: that's what's overflowing it.
The solution is to not use a fixed-size array at all, but a Vec
. The simplest way I can think of to make a Vec
of 8 million 10.0
is this:
fn main() {
const SIZE: usize = 1024 * 1024;
let v = vec![10.0; SIZE];
}
Or, if for some reason you'd rather use iterators:
use std::iter::repeat;
fn main() {
const SIZE: usize = 1024 * 1024;
let v: Vec<_> = repeat(10.0).take(SIZE).collect();
}
This should only perform a single heap allocation.
Note that you can subsequently take a Vec
and turn it into a Box<[_]>
by using the into_boxed_slice
method.
See also:
I ran into this too, and ended up first at Creating a fixed-size array on heap in Rust where you find the full answer.
The gist of the answer is this macro:
/// A macro similar to `vec![$elem; $size]` which returns a boxed array.
///
/// ```rustc
/// let _: Box<[u8; 1024]> = box_array![0; 1024];
/// ```
macro_rules! box_array {
($val:expr ; $len:expr) => {{
// Use a generic function so that the pointer cast remains type-safe
fn vec_to_boxed_array<T>(vec: Vec<T>) -> Box<[T; $len]> {
let boxed_slice = vec.into_boxed_slice();
let ptr = ::std::boxed::Box::into_raw(boxed_slice) as *mut [T; $len];
unsafe { Box::from_raw(ptr) }
}
vec_to_boxed_array(vec![$val; $len])
}};
}
which I like most, as it simply gives you what the OP wanted:
An array, and it works with stable rust.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With