Skip to content

Instantly share code, notes, and snippets.

@mlalic
Created October 8, 2015 16:51
Show Gist options
  • Select an option

  • Save mlalic/16c2f3a838d2bee844a3 to your computer and use it in GitHub Desktop.

Select an option

Save mlalic/16c2f3a838d2bee844a3 to your computer and use it in GitHub Desktop.
Unsafe double drop due to aliasing
use std::mem;
use std::ptr;
struct Foo;
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping Foo");
}
}
struct Bar {
f1: Foo,
f2: Foo,
}
impl Bar {
fn deconstruct(self) -> (Foo, Foo) {
unsafe {
let parts = (
ptr::read(&self.f1),
ptr::read(&self.f2)
);
mem::forget(self);
parts
}
}
}
impl Drop for Bar {
fn drop(&mut self) {
let res = unsafe { ptr::read(self) };
// This forget is fully useless...
mem::forget(self);
let (f1, f2) = res.deconstruct();
// The f1 and f2 in this scope now alias the same instances
// as the self.f1 and self.f2 fields do. They will end up
// dropped here as they're going out of scope. However, they'll
// be dropped again when the destructors of the `*self` instance
// are invoked...
}
}
fn main() {
let bar = Bar {
f1: Foo,
f2: Foo,
};
// bar is now dropped... The `Drop::drop` method is invoked first, but
// then its fields also recursively dropped.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment