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

Rust中从指针复制Box后如何避免二次释放问题?

Rust中重复Box导致的双释放问题及正确处理方式

问题重现

以下代码会触发双释放错误:

let a = Box::new(100);
let b = unsafe { ptr::read(&a) };

程序退出时抛出错误:

sm2-be78471d87150ecc(39668,0x7000075d5000) malloc: *** error for object 0x6000025e0000: pointer being freed was not allocated

错误原因

ptr::read(&a)直接复制了Box实例的内部指针,导致a和b两个Box持有同一块堆内存地址。当两个Box各自离开作用域触发Drop时,会尝试两次释放同一块内存,触发内存安全错误。

可选方案分析与正确结论

方案一:使用ManuallyDrop包裹第二个Box

let a = Box::new(100);
let b = ManuallyDrop::new(unsafe { ptr::read(&a) });

这个方案不会造成内存泄漏:a会在离开作用域时正常释放堆内存,而ManuallyDrop包裹的b不会自动执行Drop,因此不会触发双释放。但要注意,后续不能再访问b指向的内存,否则会访问已释放的悬空指针。

方案二:使用mem::forget跳过第二个Box的析构

let a = Box::new(100);
let b = unsafe { ptr::read(&a) };
mem::forget(b);

这个方案是正确的。mem::forget(b)明确阻止b的析构函数执行,仅保留a作为内存的唯一所有者,在a离开作用域时正常释放堆内存,既避免了双释放,也不会造成内存泄漏。

总结

如果需要通过ptr::read复制Box指针,核心原则是确保只有一个Box实例执行析构函数。mem::forget是更直观的选择,它清晰表达了“不执行该值析构”的意图;ManuallyDrop也能实现相同效果,但需要注意避免后续的悬空指针访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 10:12:26