1.8.0[][src]Function std::intrinsics::drop_in_place

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

Executes the destructor (if any) of the pointed-to value.

This is semantically equivalent to calling ptr::read and discarding the result, but has the following advantages:

Safety

Behavior is undefined if any of the following conditions are violated:

Additionally, if T is not Copy, using the pointed-to value after calling drop_in_place can cause undefined behavior. Note that *to_drop = foo counts as a use because it will cause the value to be dropped again. write can be used to overwrite data without causing it to be dropped.

Note that even if T has size 0, the pointer must be non-NULL and properly aligned.

Examples

Manually remove the last item from a 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 {
    // Get a raw pointer to the last element in `v`.
    let ptr = &mut v[1] as *mut _;
    // Shorten `v` to prevent the last item from being dropped. We do that first,
    // to prevent issues if the `drop_in_place` below panics.
    v.set_len(1);
    // Without a call `drop_in_place`, the last item would never be dropped,
    // and the memory it manages would be leaked.
    ptr::drop_in_place(ptr);
}

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

// Ensure that the last item was dropped.
assert!(weak.upgrade().is_none());Run

Unaligned values cannot be dropped in place, they must be copied to an aligned location first:

use std::ptr;
use std::mem;

unsafe fn drop_after_copy<T>(to_drop: *mut T) {
    let mut copy: T = mem::uninitialized();
    ptr::copy(to_drop, &mut copy, 1);
    drop(copy);
}

#[repr(packed, C)]
struct Packed {
    _padding: u8,
    unaligned: Vec<i32>,
}

let mut p = Packed { _padding: 0, unaligned: vec![42] };
unsafe {
    drop_after_copy(&mut p.unaligned as *mut _);
    mem::forget(p);
}Run

Notice that the compiler performs this copy automatically when dropping packed structs, i.e., you do not usually have to worry about such issues unless you call drop_in_place manually.