From dfc180db2bfccf577c9b936bda7978107c06241a Mon Sep 17 00:00:00 2001 From: Kristof Mattei <864376+kristof-mattei@users.noreply.github.com> Date: Wed, 19 Jun 2024 16:57:04 -0700 Subject: [PATCH] expand leak amplification with example Took me quite a while to understand leak amplification actually meant until I tested it in code. I think this makes it more clear. --- src/leaking.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/leaking.md b/src/leaking.md index d90fed57..9c6a25f3 100644 --- a/src/leaking.md +++ b/src/leaking.md @@ -104,6 +104,47 @@ mem::forget us in the middle of the iteration, all that does is *leak even more* Since we've accepted that mem::forget is safe, this is definitely safe. We call leaks causing more leaks a *leak amplification*. +Expanding the above example shows that elements remaining in the vector after +dropping the `drainer` are leaked: + + +```rust +use std::mem; + +struct Frob { + v: i32, +} + +impl Drop for Frob { + fn drop(&mut self) { + println!("Frob {{ v: {} }} dropped", self.v) + } +} + +fn main() { + let mut vec = (1..5).map(|v| Frob { v }).collect::>(); + + { + let mut drainer = vec.drain(..); + + drainer.next(); + drainer.next(); + + mem::forget(drainer); + } + + println!("Goodbye"); +} +``` + +Output: + +```text +Frob { v: 1 } dropped +Frob { v: 2 } dropped +Goodbye +``` + ## Rc Rc is an interesting case because at first glance it doesn't appear to be a