Function std::ptr::drop_in_place
1.8.0 · source · 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)
时,可用于丢弃 固定 数据 (在丢弃固定的数据之前,不得移动固定的数据)。
未对齐的值不能被直接丢弃,必须先使用 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