You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让堆上的boxed对象留存至程序执行结束?

问题

出于实验目的(想在堆上分配大量对象并测量其性能),编写了如下代码:

struct Foo {
    x: u32
}

for i in 0..1000 {
  let b = Box::new(Foo {x: i as u32});
  let p = b.deref();
  println!("Pointer: {:p}", p);
}

得到的输出为:

Pointer: 0x600000780000
Pointer: 0x600000780000
Pointer: 0x600000780000
Pointer: 0x600000780000
Pointer: 0x600000780000
...

所有地址相同,说明对象刚分配就被销毁了,希望避免这种情况,让对象占用的内存不被立即释放。

解决方法

核心原因是每次循环里的Box变量b在当前循环迭代结束后就会被Rust的所有权系统自动销毁,对应的堆内存也会被释放,所以下一次循环会重新复用这块地址。要保留这些对象的内存,需要延长它们的生命周期:

  • 使用容器存储所有Box:创建一个Vec<Box<Foo>>,每次循环把新创建的Box推入这个容器中。容器会持有这些Box的所有权,只要容器不被销毁,里面的所有Box对应的堆内存就会一直被占用。

修改后的代码示例:

struct Foo {
    x: u32
}

fn main() {
    // 创建一个Vec来保存所有堆分配的对象
    let mut objects = Vec::new();
    for i in 0..1000 {
        let b = Box::new(Foo { x: i as u32 });
        // 打印当前Box的指针
        println!("Pointer: {:p}", b);
        // 将Box存入Vec,延长其生命周期
        objects.push(b);
    }
    // 此时所有对象都存在于Vec中,内存未被释放
    // 可以在这里进行性能测量等操作
}

运行这段代码后,每个输出的指针都会不同,因为每个Box对应的堆内存都被容器保留,不会被立即释放。

如果只是想测试堆分配性能而不需要保留对象引用,也可以通过手动作用域延长变量生命周期,但使用容器是最符合Rust风格且稳妥的方式。

内容的提问来源于stack exchange,提问作者yegor256

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 12:52:48