当我尝试使用Rust时,我注意到如果使用Box :: new从文字创建盒装数组,则会从只读内存中额外复制到堆栈.为什么Rust编译器不能直接从只读内存复制到堆上分配的空间? Rust代码的片段:
Rust代码的片段:
fn main() { let v: Box<[u32]> = Box::new([1u32,2,3456,4,5,6]); println!("vector {}", v.len()); }
适当的汇编片段:
00000000000049d4 mov rax, qword [ds:0x39ad0] 00000000000049db mov qword [ss:rsp+arg_F8], rax 00000000000049e3 movaps xmm0, xmmword [ds:const1050] 00000000000049ea movaps xmmword [ss:rsp+arg_E8], xmm0 00000000000049f2 mov ecx, 0x18 00000000000049f7 mov edi, ecx ; argument #1 for method _ZN4heap15exchange_malloc20h356508549306a536JeaE 00000000000049f9 mov ecx, 0x4 00000000000049fe mov esi, ecx ; argument #2 for method _ZN4heap15exchange_malloc20h356508549306a536JeaE 0000000000004a00 call _ZN4heap15exchange_malloc20h356508549306a536JeaE ; heap::exchange_malloc::h356508549306a536Jea 0000000000004a05 mov rsi, qword [ss:rsp+arg_F8] 0000000000004a0d mov qword [ds:rax+0x10], rsi 0000000000004a11 movaps xmm0, xmmword [ss:rsp+arg_E8] 0000000000004a19 movups xmmword [ds:rax], xmm0
该数组位于二进制文件中的0x39ad0和const1050:
0000000000039ac8 db 0x80 ; '.' 0000000000039ac9 db 0x0d ; '.' 0000000000039aca db 0x00 ; '.' 0000000000039acb db 0x00 ; '.' 0000000000039acc db 0x04 ; '.' 0000000000039acd db 0x00 ; '.' 0000000000039ace db 0x00 ; '.' 0000000000039acf db 0x00 ; '.' 0000000000039ad0 dq 0x000000你的发现是正确的;这是Box :: new()是常规函数的结果.fn main() { let v: Box<[u32]> = Box::new([1u32,2,3456,4,5,6]); println!("vector {}", v.len()); }00005 ; XREF=_ZN4main20h90e2c514439f0097eaaE+52fn main() { let v: Box<[u32]> = Box::new([1u32,2,3456,4,5,6]); println!("vector {}", v.len()); }
将值直接放在堆上的正确方法是使用placement操作符;但是,目前在Rust中没有这样的东西,但有两个RFC,this(已接受)和this(待定,但似乎可能被接受).此外,如果您每晚使用Rust,则可以使用不稳定的框语法:
let v: Box<[u32]> = box [1u32,2,3456,4,5,6];