Function std::mem::forget
[−]
[src]
pub fn forget<T>(t: T)
Leaks a value into the void, consuming ownership and never running its destructor.
This function will take ownership of its argument, but is distinct from the
mem::drop
function in that it does not run the destructor, leaking the
value and any resources that it owns.
There's only a few reasons to use this function. They mainly come up in unsafe code or FFI code.
- You have an uninitialized value, perhaps for performance reasons, and need to prevent the destructor from running on it.
- You have two copies of a value (like when writing something like
mem::swap
), but need the destructor to only run once to prevent a doublefree
. - Transferring resources across FFI boundaries.
Safety
This function is not marked as unsafe
as Rust does not guarantee that the
Drop
implementation for a value will always run. Note, however, that
leaking resources such as memory or I/O objects is likely not desired, so
this function is only recommended for specialized use cases.
The safety of this function implies that when writing unsafe
code
yourself care must be taken when leveraging a destructor that is required to
run to preserve memory safety. There are known situations where the
destructor may not run (such as if ownership of the object with the
destructor is returned) which must be taken into account.
Other forms of Leakage
It's important to point out that this function is not the only method by which a value can be leaked in safe Rust code. Other known sources of leakage are:
Rc
andArc
cyclesmpsc::{Sender, Receiver}
cycles (they useArc
internally)- Panicking destructors are likely to leak local resources
Example
Leak some heap memory by never deallocating it:
use std::mem; let heap_memory = Box::new(3); mem::forget(heap_memory);
Leak an I/O object, never closing the file:
use std::mem; use std::fs::File; let file = File::open("foo.txt").unwrap(); mem::forget(file);
The mem::swap
function uses mem::forget
to good effect:
use std::mem; use std::ptr; fn swap<T>(x: &mut T, y: &mut T) { unsafe { // Give ourselves some scratch space to work with let mut t: T = mem::uninitialized(); // Perform the swap, `&mut` pointers never alias ptr::copy_nonoverlapping(&*x, &mut t, 1); ptr::copy_nonoverlapping(&*y, x, 1); ptr::copy_nonoverlapping(&t, y, 1); // y and t now point to the same thing, but we need to completely // forget `t` because we do not want to run the destructor for `T` // on its value, which is still owned somewhere outside this function. mem::forget(t); } }