我有以下代码段:
fn test() {
let addr = Box::new(1024);
println!("{:p}", addr);
}
fn main(){
test();
test();
}
0x7fd2fa402b70
0x7fd2fa402b70
如文档所述,Box::new
将在堆上分配内存,然后将参数放入其中。无论我调用test()
多少次,程序都会打印相同的地址。
即使代码在unsafe
块中,Rust为什么也分配相同的堆地址?这是正常行为吗?
由于您没有将结果存储在test
函数之外,因此分配的内存将立即释放。这使内存分配器可以在第二次调用之前重用相同的地址。
我认为当前的
Box::new
实现与我期望的行为不同
是,这似乎有可能,但是值得考虑[[为什么,您期望这种特定行为。对我来说,表现出来的行为是有道理的。
或至少我们应该在[Box
es] rustdoc]上评论此“优化”>无论如何,这不是对
Box
的优化。没有所有者时立即释放值的行为是Rust语言定义的一部分。
它
可以
被认为是当前正在使用的基础内存分配器的优化。但是,分配器实现对于许多程序员来说都是有意义的,并且不是Rust独有的。例如,这是C中的类似程序:#include <stdio.h>
#include <stdlib.h>
int main() {
for (int i = 0; i < 10; i++) {
int32_t *v = malloc(sizeof(int32_t));
printf("%p\n", (void *)v);
free(v);
}
}
% clang -std=c17 -Wpedantic -Wall alloc.c
% ./a.out
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
0x7f87c6401860
注意,内存分配器的实现最终导致返回相同的地址;可以编写一个不正确的内存分配器。