liveBook · Manning

Destructor

As explained in Idiomatic Rust

A destructor is cleanup behavior automatically invoked when an object is destroyed.

A destructor performs cleanup when an object is destroyed. This matters when a function can return early: a cleanup call written at the end of the function may never run. Resource acquisition is initialization (RAII) ties cleanup to an object's lifetime instead of relying on every return path to reach that call. section 4.1.1

void leaky_func() {
    FILE *fp;
    int *a = malloc(sizeof(int));
    *a = 0;                           #1

    // try to open a file for reading
    fp = fopen("file.txt", "r");
    if (fp == NULL) {
        // there was an error!
        return;
    }

    // Now we can read from the file at fp.
    // ...

    fclose(fp);        #2
    free(a);           #3
}

The failed file-open path returns before `free(a)`, leaking the allocated memory. section 4.1.1

In C++, a stack object's destructor runs when it leaves scope. A smart pointer can use that guarantee to pair allocation with release, even on an early return. The protection depends on using the smart pointer rather than managing the allocation manually. section 4.1.1

Rust also destroys an owned value when it goes out of scope. Ownership moves determine *which* variable owns the value at that point: moving a `String` into a `Vec` leaves the vector responsible for it. A container's destruction also destroys its contents. The special `Drop` trait provides a destructor through `fn drop(&mut self)`. section 4.1.2 section 2.2.5

Listing 4.1 Resource acquisition
fn main() {
    let status = String::from("Active");      #1
    let statuses = vec![status];              #2
    println!("{:?}", statuses);
}  #3

Follow `status` into `statuses`: the move transfers ownership, so cleanup follows the vector's lifetime rather than the original binding. section 4.1.2

Do not rely on a destructor for a `Copy` value. Such values are copied by value rather than moved, and a `Copy` type cannot define a destructor. For owned, non-`Copy` values, use scope and ownership to reason about when cleanup happens; keep unsafe code in mind as an exception to the ordinary RAII account. section 4.1.2

How Idiomatic Rust covers it

How deep it goes
Explains scope-triggered destruction, ownership moves, and Copy exceptions; shows Drop's signature without a custom implementation.
Examples
Contrasts a C early-return leak and C++ smart-pointer cleanup with a Rust String moved into a Vec.
What it assumes
Assumes familiarity with Rust variables and traits while explaining ownership moves through a small String-and-Vec example.
What you can do after
Evaluate/understand it to predict cleanup when owned Rust values leave scope and identify why Copy values have no destructor.
How it connects
Connects destructors to RAII, smart pointers, ownership, move semantics, Copy, and the Drop trait.

Also explained in

Compare how 3 books explain destructor →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Idiomatic Rust. The section links point to the parts of the book it draws on.