-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
the Drop example isn't good enough #1843
Comments
And if you wanted to implement your own drop() for the inner fields, how would you do it? Maybe this way?(playground) (or is there another, perhaps more idiomatic one?) use std::mem::ManuallyDrop;
struct Inner {
name: String,
}
impl Inner {
fn new(name: &str) -> Self {
println!("Creating Inner: {}", name);
Inner {
name: name.to_string(),
}
}
}
impl Drop for Inner {
fn drop(&mut self) {
println!("Dropping Inner: {}", self.name);
}
}
struct Parent {
inner1: ManuallyDrop<Inner>,
inner2: ManuallyDrop<Inner>,
}
impl Parent {
fn new() -> Self {
println!("Creating Parent");
Parent {
inner2: ManuallyDrop::new(Inner::new("Inner 2i")),
inner1: ManuallyDrop::new(Inner::new("Inner 1i")),
}
}
fn new2(i1:Inner, i2:Inner) -> Self {
println!("Creating Parent");
Parent {
inner1: ManuallyDrop::new(i1),
inner2: ManuallyDrop::new(i2),
}
}
}
impl Drop for Parent {
fn drop(&mut self) {
println!("Dropping Parent, manually dropping begins:");
//Dropping these in reverse order (manually), just for kicks
unsafe { std::mem::ManuallyDrop::drop(&mut self.inner2) };
unsafe { std::mem::ManuallyDrop::drop(&mut self.inner1) };
//technically can still see/use them hereafter still, but it's UB?!
println!("Dropping Parent done manually dropping");
}
}
fn main() {
{
println!("Example1:");
{
let _parent = Parent::new();
}
println!("Example2:");
{
//the order of the inners creation does not matter when dropping them, they're dropped in field order
let inner2 = Inner::new("New Inner 2");
let inner1 = Inner::new("New Inner 1");
//but it doesn't matter which parent/inners were created first
//in either of the 3 examples in main()
let _parent = Parent::new2(inner1, inner2);
}
println!("Example3:");
let mut parent = Parent::new();
// Set inner fields to new Inner objects
parent.inner2 = ManuallyDrop::new(Inner::new("New Inner 2"));
parent.inner1 = ManuallyDrop::new(Inner::new("New Inner 1"));
println!("Exiting inner scope");
}
println!("Exiting main scope");
} output:
EDIT: Notice how the old ones that got replaced directly got leaked. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
in https://doc.rust-lang.org/rust-by-example/trait/drop.html
there's no example showing how drop() happens in case of inner fields:
the parent struct's
drop()
gets executed first then the fields' are executed in declaration order(instead of reverse order akaUnlike for structs, local variables are dropped in reverse order
) of which they were created.This seems like an important distinction, even though it's covered in the docs. But not important enough that I figure out how to mod the example via a PR, so this is left for someone far more capable than I :)
This examplifies the above (playground]:
output:
The text was updated successfully, but these errors were encountered: