如何正确释放堆分配的内存?

huangapple go评论53阅读模式
英文:

Rust, how do i correctly free heap allocated memory?

问题

I wanted to reinvent the wheel(reference counting smart pointer) and i am not sure how to properly free the memory leaked with Box::into_raw(), once the references go to zero I don't know how to efficiently free the memory that is being pointed.

I originally went with:

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");
        }
    }
}

But I was wondering if ptr::drop_in_place() would work the same, if not better, since it won't have to make a Box just to drop it.

英文:

I wanted to reinvent the wheel(reference counting smart pointer) and i am not sure how to properly free the memory leaked with Box::into_raw() , once the references go to zero i don't know how to efficiently free the memory that is being pointed

I originally went with

impl&lt;T&gt; Drop for SafePtr&lt;T&gt;{
    fn drop(&amp;mut self) {
        //println!(&quot;drop, {} refs&quot;, 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!(&quot;Dropped all pointed values&quot;);
        };
    }
}

but i was wondering if ptr::drop_in_place() would work the same if not better since it won't have to make a Box just to drop it

答案1

得分: 4

根据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>());
}

出于性能考虑,这两种方法编译成完全相同的指令,所以我会使用drop(Box::from_raw(ptr)),以避免记住何时使用dealloc

英文:

As you can see from the documentation on into_raw just drop_in_place is not enough, to free the memory you also have to call dealloc:
> rust
&gt; use std::alloc::{dealloc, Layout};
&gt; use std::ptr;
&gt;
&gt; let x = Box::new(String::from(&quot;Hello&quot;));
&gt; let p = Box::into_raw(x);
&gt; unsafe {
&gt; ptr::drop_in_place(p);
&gt; dealloc(p as *mut u8, Layout::new::&lt;String&gt;());
&gt; }
&gt;

For performance considerations, both methods compile to the exact same instructions, so I'd just use drop(Box::from_raw(ptr)) to save me the hussle remembering the dealloc where applicable.

huangapple
  • 本文由 发表于 2023年2月14日 05:08:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75441199.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定