我想重新发明轮子(引用计数智能指针),但我不确定如何正确释放与Box::into_raw()泄漏的内存,一旦引用变为零,我不知道如何有效地释放被指向的内存

我最初选的是

impl<T> Drop for SafePtr<T>{
    fn drop(&mut self) {
        //println!("drop, {} refs", self.get_refs());
        self.dec_refs();
        let ref_count = self.get_refs();
        if ref_count == 0usize{
            unsafe{
                let _ = Box::from_raw(self.ptr);
                let _ = Box::from_raw(self.refs);
            };
            println!("Dropped all pointed values");
        };
    }
}

但我想知道ptr::drop_in_place()是不是也会一样好,因为它不需要做一个盒子就能把它扔了

推荐答案

正如您可以从关于into_raw的文档中看到的那样,仅drop_in_place是不够的,要释放内存,您还必须调用dealloc:

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

let x = Box::new(String::from("Hello"));
let p = Box::into_raw(x);
unsafe {
    ptr::drop_in_place(p);
    dealloc(p as *mut u8, Layout::new::<String>());
}

出于性能方面的考虑,这两种方法都是compile to the exact same instructions,所以我只使用drop(Box::from_raw(ptr))来省go 我在适用的情况下记住dealloc的麻烦.

Rust相关问答推荐

MacOS(AARCH64)上Ghidra中的二进制补丁导致进程终止

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

MutexGuard中的过滤载体不需要克隆

在自定义序列化程序中复制serde(With)的行为

当T不执行Copy时,如何返回Arc Mutex T后面的值?

是否可以在不切换到下一个位置的情况下获得迭代器值:

在文件链实施中绕过borrow 判断器

如何实现Deref;多次;?

Rust 中的静态引用

如何迭代存储在 struct 中的字符串向量而不移动它们?

在发布中包含 Rust DLL

Rust中如何实现一个与Sized相反的负特性(Unsized)

有什么办法可以追踪泛型的单态化过程吗?

如何在 Rust 中将枚举变体转换为 u8?

在线程中运行时,TCPListener(服务器)在 ip 列表中的服务器实例之前没有从客户端接受所有客户端的请求

在单独的线程上运行 actix web 服务器

如何为返回正确类型的枚举实现 get 方法?

如何创建动态创建值并向它们返回borrow 的工厂?

为什么 std::iter::Peekable::peek 可变地borrow self 参数?

为什么我不能将元素写入 Rust 数组中移动的位置,但我可以在元组中完成