In this code...
struct Test { a: i32, b: i64 }
fn foo() -> Box { // Stack frame:
As of Rust 1.39, there seems to be only one way in stable to allocate memory on the heap directly - by using std::alloc::alloc (note that the docs state that it is expected to be deprecated). It's reasonably unsafe.
Example:
#[derive(Debug)]
struct Test {
a: i64,
b: &'static str,
}
fn main() {
use std::alloc::{alloc, dealloc, Layout};
unsafe {
let layout = Layout::new::<Test>();
let ptr = alloc(layout) as *mut Test;
(*ptr).a = 42;
(*ptr).b = "testing";
let bx = Box::from_raw(ptr);
println!("{:?}", bx);
}
}
This approach is used in the unstable method Box::new_uninit.
It turns out there's even a crate for avoiding memcpy
calls (among other things): copyless. This crate also uses an approach based on this.
You seem to be looking for the box_syntax feature, however as of Rust 1.39.0 it is not stable and only available with a nightly compiler. It also seems like this feature will not be stabilized any time soon, and might have a different design if it ever gets stabilized.
On a nightly compiler, you can write:
#![feature(box_syntax)]
struct Test { a: i32, b: i64 }
fn foo() -> Box<Test> {
box Test { a: 123, b: 456 }
}
Is there a way to allocate directly to the heap without
box
?
No. If there was, it wouldn't need a language change.
People tend to avoid this by using the unstable syntax indirectly, such as by using one of the standard containers which, in turn, uses it internally.
See also:
I recently had the same problem. Based on the answers here and other places, I wrote a simple function for heap allocation:
pub fn unsafe_allocate<T>() -> Box<T> {
let mut grid_box: Box<T>;
unsafe {
use std::alloc::{alloc, dealloc, Layout};
let layout = Layout::new::<T>();
let ptr = alloc(layout) as *mut T;
grid_box = Box::from_raw(ptr);
}
return grid_box;
}
This will create a region in memory automatically sized after T
and unsafely convince Rust that that memory region is an actual T
value. The memory may contain arbitrary data; you should not assume all values are 0.
Example use:
let mut triangles: Box<[Triangle; 100000]> = unsafe_allocate::<[Triangle; 100000]>();