I’m currently trying to understand how drop
works. The following code crashes and I don’t understand why. From my understanding, the usage of std::ptr::write
should prevent the destructor (edit: of the original value, here: Rc) from running (in this case nothing bad should happen beside the memory leak). But it doesn’t seem to do that as (playpen, compile with -O0)
use std::rc::Rc;
use std::mem;
use std::ptr;
enum Foo {
Bar(Rc<usize>),
Baz
}
use Foo::*;
impl Drop for Foo {
fn drop(&mut self) {
match *self {
Bar(_) => {
unsafe { ptr::write(self, Foo::Baz) }
//unsafe { mem::forget(mem::replace(self, Foo::Baz)) }
}
Baz => ()
}
}
}
fn main() {
let _ = Foo::Bar(Rc::new(23));
}
gives an overflow error:
thread '<main>' panicked at 'arithmetic operation overflowed', /Users/rustbuild/src/rust-buildbot/slave/nightly-dist-rustc-mac/build/src/liballoc/rc.rs:755
The other variant quits with an illegal instruction. Why does that happen? How can I replace self with a value that will be properly dropped?
I'm not sure yet how to accomplish your goal, butI can show thatisn't true:
This prints:
Indicating that the destructor for
Foo::Bar
is still being run, including the destructor ofNoisy
.A potential solution is to use
Option::take
: