Function std::ptr::drop_in_place1.8.0[][src]

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

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

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

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

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

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

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

Safety

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

  • to_drop 对于读写,必须为 有效 的。

  • to_drop 必须正确对齐。

  • to_drop 指向的值必须对丢弃有效,这可能意味着它必须支持其他不变式 - 这与类型有关。

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

请注意,即使 T 的大小为 0,指针也必须非空且正确对齐。

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

注意,编译器在丢弃包装好的结构时会自动执行这种复制,即,除非您手动调用 drop_in_place,否则通常不必担心此类问题。