# Function ethcore_util::standard::mem::forget 1.0.0 [−] [src]

    pub fn forget<T>(t: T)

Leaks a value: takes ownership and "forgets" about the value without running its destructor.

Any resources the value manages, such as heap memory or a file handle, will linger forever in an unreachable state.

If you want to dispose of a value properly, running its destructor, see `mem::drop`.

# Safety

`forget` is not marked as `unsafe`, because Rust's safety guarantees do not include a guarantee that destructors will always run. For example, a program can create a reference cycle using `Rc`, or call `process:exit` to exit without running destructors. Thus, allowing `mem::forget` from safe code does not fundamentally change Rust's safety guarantees.

That said, leaking resources such as memory or I/O objects is usually undesirable, so `forget` is only recommended for specialized use cases like those shown below.

Because forgetting a value is allowed, any `unsafe` code you write must allow for this possibility. You cannot return a value and expect that the caller will necessarily run the value's destructor.

# Examples

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 practical use cases for `forget` are rather specialized and mainly come up in unsafe or FFI code.

## Use case 1

You have created an uninitialized value using `mem::uninitialized`. You must either initialize or `forget` it on every computation path before Rust drops it automatically, like at the end of a scope or after a panic. Running the destructor on an uninitialized value would be undefined behavior.

    use std::mem;
    use std::ptr;

    unsafe {
        let mut uninit_vec: Vec<u32> = mem::uninitialized();

        if some_condition {
            // Initialize the variable.
            ptr::write(&mut uninit_vec, Vec::new());
        } else {
            // Forget the uninitialized value so its destructor doesn't run.
            mem::forget(uninit_vec);
        }
    }

## Use case 2

You have duplicated the bytes making up a value, without doing a proper `Clone`. You need the value's destructor to run only once, because a double `free` is undefined behavior.

An example is the definition of `mem::swap` in this module:

    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);
        }
    }

## Use case 3

You are transferring ownership across a FFI boundary to code written in another language. You need to `forget` the value on the Rust side because Rust code is no longer responsible for it.

    use std::mem;

    extern "C" {
        fn my_c_function(x: *const u32);
    }

    let x: Box<u32> = Box::new(3);

    // Transfer ownership into C code.
    unsafe {
        my_c_function(&*x);
    }
    mem::forget(x);

In this case, C code must call back into Rust to free the object. Calling C's `free` function on a `Box` is not safe! Also, `Box` provides an `into_raw` method which is the preferred way to do this in practice.

# Help

## Keyboard Shortcuts

?
  Show this help dialog
S
  Focus the search field
⇤
  Move up in search results
⇥
  Move down in search results
⏎
  Go to active search result
+
  Collapse/expand all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)