How to allocate structs on the heap without taking up space on the stack in stable Rust?

前端 未结 4 452
北荒
北荒 2020-12-19 07:45

In this code...

struct Test { a: i32, b: i64 }
    
fn foo() -> Box {              // Stack frame:
            


        
相关标签:
4条回答
  • 2020-12-19 08:11

    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.

    0 讨论(0)
  • 2020-12-19 08:17

    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 }
    }
    
    0 讨论(0)
  • 2020-12-19 08:23

    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:

    • How to allocate arrays on the heap in Rust 1.0?
    • Is there any way to allocate a standard Rust array directly on the heap, skipping the stack entirely?
    • What does the box keyword do?
    • What is the <- symbol in Rust?
    0 讨论(0)
  • 2020-12-19 08:34

    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]>();
    
    0 讨论(0)
提交回复
热议问题