You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
All assertions pass. Each test has a similar structure; here's a minimal example using LinkedList that recreates the issue:
let mut l = LinkedList::new(ObjAdapter1::new());
let a = make_obj(1);
l.cursor_mut().insert_before(a.clone());
l.fast_clear();
unsafe {
a.link1.force_unlink();
}
When executing this, Miri detects that a is leaked and provides the following output:
I originally thought this was due to unwrapping the clone in insert_before(...). To test this, I switched to using a modified ObjAdapter3 with Weak instead of Rc, and passed Rc::downgrade(&a) as a parameter to insert_before instead of making a clone. However, this did not correct the issue.
Given the descriptions of both force_unlink and fast_clear, I'm guessing that there are always going to be some precautions necessary to avoid memory leaks here. Could you confirm if this is a bug, and if not, what additional steps a user would need to take to avoid this type of leak when using these methods? Thanks!
The text was updated successfully, but these errors were encountered:
icmccorm
changed the title
Calling fast_clear causes a memory leak when using Rc, even if force_unlinnk is called on each object
Calling fast_clear causes a memory leak when using Rc, even if force_unlink is called on each object
Feb 9, 2023
icmccorm
changed the title
Calling fast_clear causes a memory leak when using Rc, even if force_unlink is called on each object
Calling fast_clear causes a memory leak when using Rc<T>, even if force_unlink is called on each linked object.
Feb 9, 2023
I think this is not so much a bug as poor API design. force_unlink was originally designed to be used with UnsafeRef where the lifetimes of objects are manually managed: you could fast_clear a list and then re-use the existing objects in another list by force_unlinking them.
This was never designed to work with proper pointer types such as Box or Rc.
I'm new to working with Rc, so I had thought that you could get around this with a change to using Weak, but from the docs:
Since a Weak reference does not count towards ownership, it will not prevent the value stored in the allocation from being dropped... Note however that a Weak reference does prevent the allocation itself (the backing store) from being deallocated.
And, sure enough, the same kind of leak will happen with a pretty minimal example:
use std::{rc::{Rc, Weak}};
fn main() {
let a = Rc::new(Box::new(1));
Weak::into_raw(Rc::downgrade(&a));
}
The pull request above eliminates the leak by switching away from Rc to UnsafeRef for the these test cases.
Miri found memory leaks in the following tests:
All assertions pass. Each test has a similar structure; here's a minimal example using
LinkedList
that recreates the issue:When executing this, Miri detects that
a
is leaked and provides the following output:I originally thought this was due to unwrapping the clone in
insert_before(...)
. To test this, I switched to using a modified ObjAdapter3 with Weak instead of Rc, and passedRc::downgrade(&a)
as a parameter toinsert_before
instead of making a clone. However, this did not correct the issue.Given the descriptions of both
force_unlink
andfast_clear
, I'm guessing that there are always going to be some precautions necessary to avoid memory leaks here. Could you confirm if this is a bug, and if not, what additional steps a user would need to take to avoid this type of leak when using these methods? Thanks!The text was updated successfully, but these errors were encountered: