Skip to content

Commit

Permalink
fix memory leak when vec::IntoIter panics during drop
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Mar 8, 2020
1 parent f943349 commit 528cbc4
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/liballoc/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2626,13 +2626,21 @@ impl<T: Clone> Clone for IntoIter<T> {
#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T> Drop for IntoIter<T> {
fn drop(&mut self) {
struct DropGuard<'a, T>(&'a mut IntoIter<T>);

impl<T> Drop for DropGuard<'_, T> {
fn drop(&mut self) {
// RawVec handles deallocation
let _ = unsafe { RawVec::from_raw_parts(self.0.buf.as_ptr(), self.0.cap) };
}
}

let guard = DropGuard(self);
// destroy the remaining elements
unsafe {
ptr::drop_in_place(self.as_mut_slice());
ptr::drop_in_place(guard.0.as_mut_slice());
}

// RawVec handles deallocation
let _ = unsafe { RawVec::from_raw_parts(self.buf.as_ptr(), self.cap) };
// now `guard` will be dropped and do the rest
}
}

Expand Down

0 comments on commit 528cbc4

Please sign in to comment.