Memory management 为什么调用Box::new两次而不存储结果会分配相同的堆地址?

Memory management 为什么调用Box::new两次而不存储结果会分配相同的堆地址?,memory-management,rust,Memory Management,Rust,我有以下代码片段: fn test() { let addr = Box::new(1024); println!("{:p}", addr); } fn main(){ test(); test(); } 0x7fd2fa402b70 0x7fd2fa402b70 正如文档所解释的,Box::new将在堆上分配内存,然后将参数放入堆中。无论我调用test多少次,程序都会打印一个相同的地址 为什么Rust分配相同的堆地址,即使代码位于不安全的块中?这是正常行为

我有以下代码片段:

fn test() {
    let addr = Box::new(1024);
    println!("{:p}", addr);
}

fn main(){
    test();
    test();
}
0x7fd2fa402b70 0x7fd2fa402b70 正如文档所解释的,Box::new将在堆上分配内存,然后将参数放入堆中。无论我调用test多少次,程序都会打印一个相同的地址


为什么Rust分配相同的堆地址,即使代码位于不安全的块中?这是正常行为吗?

因为您没有将结果存储在测试函数之外,所以分配的内存会立即被释放。这允许内存分配器在第二次调用时重用相同的地址


我认为当前的Box::新实现的行为与我预期的不同

是的,这似乎是可能的,但值得思考的是,为什么你会期望这种特定的行为。对我来说,被证明的行为是有道理的

或者至少我们应该在[Box]rustdoc上评论这个优化

无论如何,这并不是对Box的优化。在值没有所有者时释放该值的行为是Rust语言定义的一部分

它可以被认为是对目前正在使用的底层内存分配器的优化。然而,分配器实现对许多程序员来说是有意义的,而且它不是Rust独有的。例如,这里有一个类似的C语言程序:

包括 包括 int main{ 对于int i=0;i<10;i++{ int32_t*v=mallocsizeofind32_t; printf%p\n,void*v; 弗里夫; } } %叮当声-std=c17-Wpedantic-Wall alloc.c %/a.out 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860
请注意,内存分配器的实现是最终导致返回相同地址的原因;可以在不正确的地方编写内存分配器。

由于没有在测试函数之外存储结果,分配的内存会立即释放。这允许内存分配器在第二次调用时重用相同的地址


我认为当前的Box::新实现的行为与我预期的不同

是的,这似乎是可能的,但值得思考的是,为什么你会期望这种特定的行为。对我来说,被证明的行为是有道理的

或者至少我们应该在[Box]rustdoc上评论这个优化

无论如何,这并不是对Box的优化。在值没有所有者时释放该值的行为是Rust语言定义的一部分

它可以被认为是对目前正在使用的底层内存分配器的优化。然而,分配器实现对许多程序员来说是有意义的,而且它不是Rust独有的。例如,这里有一个类似的C语言程序:

包括 包括 int main{ 对于int i=0;i<10;i++{ int32_t*v=mallocsizeofind32_t; printf%p\n,void*v; 弗里夫; } } %叮当声-std=c17-Wpedantic-Wall alloc.c %/a.out 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860 0x7f87c6401860
请注意,内存分配器的实现是最终导致返回相同地址的原因;可以在不正确的地方编写内存分配器。

我认为当前Box::新实现的行为与我预期的不同,或者至少我们应该在它的rustdoc上注释此优化。@racaljk这几乎不是一个优化。事实上,这正是我所期望的。如果你只是连续一百万次创建和释放一个i32,你认为它们都有不同的地址吗?这将是对空间的巨大浪费。我认为当前的Box::新实现的行为与我预期的不同,或者至少我们应该对它的rustdoc进行评论。@racaljk这很难算是一个优化。事实上,这正是我所期望的。如果你只是连续一百万次创建和释放一个i32,你认为它们都有不同的地址吗?这将是一个巨大的空间浪费。是的,删除Box时将释放资源。但如果我的场景是,我的下一个人工输入取决于该堆地址的先前控制台输出,该怎么办。或者将此地址强制转换为整数,并将其存储到磁盘文件中以供进一步使用use@racaljk在这种情况下,你可能一开始就不会把盒子掉下来。删除时,您将释放内存。是的,删除时Box将释放资源。但如果我的场景是,我的下一个人工输入取决于该堆地址的先前控制台输出,该怎么办。或者将此地址强制转换为整数,并将其存储到磁盘文件中以供进一步使用use@racaljk在这种情况下,你可能一开始就不会把盒子掉下来。删除时,您将释放内存。