liveBook · Manning

Resource leak

As explained in 100 C++ Mistakes and How to Avoid Them

A resource leak is a failure to release an acquired resource, leaving it allocated or unavailable for reuse.

A resource leak occurs when acquired capacity is not released, leaving it allocated or unavailable for reuse. In C++, exceptions and immediate termination expose this mistake: destructors may not run, so database connections, sockets, files, or dynamic memory remain held. section 5.9 section 10.4

Recognize the main failure patterns:

  • Calling exit bypasses normal scope cleanup, preventing local Connection destructors from returning connections to the pool. section 5.9
  • Throwing from a constructor after allocating memory can leak that allocation because the incomplete object’s destructor does not run. section 10.4
  • Using RAII requires clear ownership; transferring a pointer to a managing object while the creator still manages it creates ownership confusion. section 10.5
  • Returning heap pointers may avoid dangling locals but shifts deletion responsibility to callers and can create further leaks. section 11.4

Termination versus unwinding

With Connection c("payroll") in scope, exit(-1) ends the program before c’s destructor can release the database resource. Replacing exit with an exception and catching at the outer boundary allows stack unwinding to destroy c. For constructor failures, release manually before throwing, or arrange exclusive ownership so cleanup remains automatic. section 5.9 section 10.4 section 10.5

Listing 5.20 Terminating a program with exit
class Connection {
private:
    int conn;
public:
    Connection(const std::string& name) : conn(0) {
        conn = 1;  // assume: database connection resource is returned
    }
    ~Connection() {
        if (conn)
            conn = 0;  // assume: destroys database connection resource
        std::cerr << "Connection destroyed\n";
    }
};
 
struct Employee {
    bool isTerminated() { return true; }
    double computePay() { return 42.0; }
};
 
int main() {
    Connection c("payroll");
    Employee emp;
    if (emp.isTerminated())
        exit(-1);                                         #1
    std::cout << emp.computePay() << '\n';
    return 0;
}

Inspect the terminating example and identify the resource whose destructor is skipped. section 5.9

Listing 5.21 Terminating a program with an exception
class Connection {
private:
    int conn;
public:
    Connection(const std::string& name) : conn(0) {
        conn = 1;  // assume: database connection resource is allocated
    }
    ~Connection() {
        if (conn)
            conn = 0;  // assume: returns database connection to pool
        std::cerr << "Connection destroyed\n";
    }
};
  
struct Employee {
    bool isTerminated() { return true; }
    double computePay() { return 42.0; }
};
 
struct TerminatedEmployee {
    std::string message;
    TerminatedEmployee(const std::string& msg) : message(msg) {}
};
 
int main() {
    try {
        Connection c("payroll");
        Employee emp;
        if (emp.isTerminated())
            throw TerminatedEmployee("Employee was terminated");
        std::cout << emp.computePay() << '\n';
    } catch (...) {
        throw;                                         #1
    }
    return 0;
}

Compare exception-based termination with exit and follow the cleanup path during unwinding. section 5.9

How 100 C++ Mistakes and How to Avoid Them covers it

How deep it goes
Explains failure paths with code and cleanup traces, then stops short of redesigning legacy systems comprehensively.
Examples
Uses database connections, file-backed page text, dynamic grade arrays, and locally returned strings as failure examples.
What it assumes
Assumes basic C++ knowledge of constructors, destructors, exceptions, pointers, and dynamic allocation.
What you can do after
Diagnose/debug with it by tracing ownership, destructor execution, exception paths, and cleanup responsibility.
How it connects
Connects resource leaks to exceptions, destructors, RAII, ownership, dynamic allocation, and stack unwinding.

Also explained in

Compare how 3 books explain resource leak →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 C++ Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.