Function core::ptr::drop_in_place

1.8.0 · source ·
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T)
Expand description

执行指向值的析构函数 (如果有)。

从语义上讲,这等效于调用 ptr::read 并丢弃结果,但是具有以下优点:

  • 强制要求使用 drop_in_place 丢弃未定义大小的类型 (例如 trait 对象),因为它们无法被读取到栈上并且无法正常丢弃。

  • 当丢弃手动分配的内存时 (例如,在 Box/Rc/Vec 的实现中),通过 ptr::read 进行此操作对优化器来说更友好,因为编译器不需要证明丢弃副本是合理的。

  • T 不是 repr(packed) 时,可用于丢弃 固定 数据 (在丢弃固定的数据之前,不得移动固定的数据)。

未对齐的值不能被直接丢弃,必须先使用 ptr::read_unaligned 将它们复制到对齐的位置。对于包装的结构体,此移动由编译器自动完成。 这意味着已打包结构的字段不会被原地丢弃。

Safety

如果违反以下任一条件,则行为是未定义的:

  • 对于读取和写入,to_drop 必须是 有效

  • to_drop 必须正确对齐,即使 T 有大小 0.

  • to_drop 必须是非空的,即使 T 有大小 0.

  • to_drop 指向的值必须对抛弃有效,这可能意味着它必须支持额外的不,变体。这些不变体,取决于丢弃的值的类型。 例如,当丢弃一个 Box 时,box 的,指向堆的指针必须是有效的。

  • drop_in_place 正在执行时,访问 to_drop 部分的唯一方法是通过提供给 drop_in_place 调用的 Drop::drop 方法的 &mut self 引用。

此外,如果 T 不是 Copy,则在调用 drop_in_place 之后使用指向的值可能会导致未定义的行为。请注意,*to_drop = foo 被视为使用,因为它将导致该值再次被丢弃。 write() 可用于覆盖数据,而不会导致数据被丢弃。

Examples

从 vector 手动删除最后一个项:

use std::ptr;
use std::rc::Rc;

let last = Rc::new(1);
let weak = Rc::downgrade(&last);

let mut v = vec![Rc::new(0), last];

unsafe {
    // 获取指向 `v` 中最后一个元素的裸指针。
    let ptr = &mut v[1] as *mut _;
    // 缩短 `v`,以防止丢弃最后一个项。
    // 我们首先这样做是为了防止 `drop_in_place` 低于 panics。
    v.set_len(1);
    // 如果没有调用 `drop_in_place`,则最后一个项将永远不会被删除,并且它管理的内存也会泄漏。
    ptr::drop_in_place(ptr);
}

assert_eq!(v, &[0.into()]);

// 确保丢弃了最后一项。
assert!(weak.upgrade().is_none());
Run