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

如何正确释放堆内存?自定义引用计数智能指针的内存释放疑问

关于引用计数智能指针的内存释放问题

首先明确两个操作的核心区别:

  • Box::from_raw(ptr):会将Box::into_raw()得到的原始指针重新包装为Box,当这个临时Box被销毁时,同时完成两件事:调用T的Drop析构函数,以及释放Box当初分配的底层内存。这完全匹配你用Box::into_raw()泄漏内存的场景,是最直接的回收方式。
  • ptr::drop_in_place(ptr):仅调用T的析构函数,不会释放内存。如果用它,你还需要手动调用alloc::dealloc来释放内存块,而且必须准确传入当初分配的内存大小和对齐方式——这不仅增加了代码复杂度,还容易因为参数错误导致内存泄漏或UB(未定义行为)。

看你的现有实现,用Box::from_raw是完全正确的,而且没有额外开销:Box::from_raw只是对指针的零成本包装,销毁临时Box的逻辑和直接销毁原Box完全一致,不存在效率问题。

如果强行换成drop_in_place,代码会变得更繁琐且易出错(需要引入alloc模块):

use std::alloc::{dealloc, Layout};

impl<T> Drop for SafePtr<T>{
    fn drop(&mut self) {
        self.dec_refs();
        let ref_count = self.get_refs();
        if ref_count == 0usize{
            unsafe{
                // 仅调用目标对象的析构函数
                std::ptr::drop_in_place(self.ptr);
                // 手动释放内存,必须保证Layout与Box分配时完全一致
                dealloc(self.ptr as *mut u8, Layout::new::<T>());
                
                // 引用计数的内存也要重复同样的步骤
                std::ptr::drop_in_place(self.refs);
                dealloc(self.refs as *mut u8, Layout::new::<usize>());
            };
            println!("Dropped all pointed values");
        };
    }
}

总结:如果你的指针来自Box::into_raw(),优先用Box::from_raw()回收,没必要换成drop_in_place——它既不更高效,还大幅增加了出错风险。

内容的提问来源于stack exchange,提问作者Eto on a mill

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:00:59