在这段代码...
struct Test { a: i32, b: i64 }
fn foo() -> Box<Test> { // Stack frame:
let v = Test { a: 123, b: 456 }; // 12 bytes
Box::new(v) // `usize` bytes (`*const T` in `Box`)
}
Run Code Online (Sandbox Code Playgroud)
...据我所知(忽略可能的优化),v在堆栈上分配然后复制到堆中,然后以Box.
而这段代码...
fn foo() -> Box<Test> {
Box::new(Test { a: 123, b: 456 })
}
Run Code Online (Sandbox Code Playgroud)
...应该没有任何不同,大概是因为应该有一个用于结构分配的临时变量(假设编译器对内部的实例化表达式没有任何特殊语义Box::new())。
我发现返回位置的值总是在父堆栈帧或接收框中分配吗?. 关于我的具体问题,它只提出实验性box语法,但主要讨论编译器优化(复制省略)。
所以我的问题仍然存在:使用稳定的Rust,如何struct在不依赖编译器优化的情况下直接在堆上分配s?
您似乎正在寻找该box_syntax功能,但是从 Rust 1.39.0 开始,它不稳定,只能在夜间编译器中使用。这个功能似乎也不会很快稳定下来,如果稳定下来,可能会有不同的设计。
在夜间编译器上,您可以编写:
#![feature(box_syntax)]
struct Test { a: i32, b: i64 }
fn foo() -> Box<Test> {
box Test { a: 123, b: 456 }
}
Run Code Online (Sandbox Code Playgroud)
从 Rust 1.39 开始,似乎只有一种稳定的方法可以直接在堆上分配内存 - 通过使用 std::alloc::alloc(请注意,文档声明它预计将被弃用)。这是相当不安全的。
例子:
#[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);
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法用于不稳定的方法 Box::new_uninit。
事实证明,甚至还有一个用于避免memcpy调用的板条箱(除其他外):copyless。这个 crate 也使用了一种基于此的方法。
| 归档时间: |
|
| 查看次数: |
1377 次 |
| 最近记录: |