gpt4 book ai didi

pointers - Rust Global.dealloc vs ptr::drop_in_place vs ManuallyDrop

转载 作者:行者123 更新时间:2023-12-03 11:45:10 24 4
gpt4 key购买 nike

我对 Rust 比较陌生。我正在研究一些无锁算法,并开始尝试手动管理内存,类似于 C++ new/delete。我注意到在整个标准库组件中有几种不同的方法可以做到这一点,但我想真正了解每种方法的差异和用例。这就是我的感觉:ManuallyDrop<Box<T>>将阻止 Box 的析构函数运行。我可以保存指向 ManuallyDrop 的原始指针元素,并让实际元素超出范围(通常在 Rust 中会被删除)而不被删除。我可以稍后调用 ManuallyDrop::drop(&mut *ptr)手动删除此值。
我也可以取消引用 ManuallyDrop<Box<T>>元素,保存一个指向 Box<T> 的原始指针,然后调用 std::ptr::drop_in_place(box_ptr) .这应该会破坏 Box本身并删除堆分配的T .
看着ManuallyDrop::drop实现,看起来那些实际上是在做完全相同的事情。由于ManuallyDrop是零成本,只是在它的结构中存储一个值,上述两种方法有什么区别吗?
我也可以调用std::alloc::Global.dealloc(...) ,看起来它会在不调用 drop 的情况下释放内存块。因此,如果我在指向 Box<T> 的指针上调用它,它将释放堆指针,但不会调用 drop , 所以 T仍然会躺在堆上。我可以在指向 T 的指针上调用它本身,这将删除 T .
通过探索标准库,它看起来像 Global.deallocraw_vec 中调用实际删除 Vec 的堆分配数组的实现指着。这是有道理的,因为它实际上是在尝试删除一 block 内存。Rc有一个大致如下所示的 drop 实现:

// destroy the contained object
ptr::drop_in_place(self.ptr.as_mut());

// remove the implicit "strong weak" pointer now that we've
// destroyed the contents.
self.dec_weak();

if self.weak() == 0 {
Global.dealloc(self.ptr.cast(), Layout::for_value(self.ptr.as_ref()));
}
我真的不明白为什么它需要 deallocdrop_in_place . dealloc 是什么意思添加 drop_in_place不行吗?
另外,如果我只是通过执行 Box::new(5).into_raw() 之类的操作来保存指向堆分配值的原始指针,我的指针现在是否控制该内存分配。如,在我明确调用 ptr::drop_in_place() 之前它会一直存在吗? ?
最后,当我在玩这一切时,我遇到了一个奇怪的问题。运行后 ManuallyDrop::dropptr::drop_in_place在我的原始指针上,然后我尝试运行 println!在指针的取消引用值上。有时我得到一个可怕的堆错误,我的测试失败了,这是我所期望的。其他时候,它只打印相同的值,就好像没有发生任何下降一样。我也试过运行 ManuallyDrop::drop多次在完全相同的值上,同样的事情。有时是堆错误,有时完全没问题,并且打印出相同的值。
这里发生了什么?

最佳答案

如果你来自C++,你可以想到drop_in_place就像手动调用析构函数一样,dealloc调用旧 C free .
它们有不同的用途:

  • drop_in_place只需调用Drop::drop ,释放你的类型持有的资源。
  • dealloc释放由指针指向的内存,之前用 alloc 分配.

  • 你似乎认为 drop_in_place也释放内存,但事实并非如此。我认为你的困惑是因为 Box<T>包含一个动态分配的对象,所以它的 Box::drop在调用它的 drop_in_place 之后,实现确实释放了该对象使用的内存。 , 当然。
    这就是您在 Rc 中看到的内容。实现,首先它调用 drop_in_place (析构函数)内部对象,然后它释放内存。
    如果您调用 drop_in_place 会发生什么连续几次......好吧,这个函数不安全是有原因的:你很可能会得到未定义的行为。从文档:

    ...if T is not Copy, using the pointed-to value after calling drop_in_place can cause undefined behavior.


    注意 can cause .我认为完全可以编写一个允许调用 drop 的类型。几次,但这听起来不是一个好主意。

    关于pointers - Rust Global.dealloc vs ptr::drop_in_place vs ManuallyDrop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62917242/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com