Background:
C++ was originally designed with a focus on performance, and therefore resource management (memory, files, streams, sockets) often occurs manually. When an exception occurs, it's necessary to clean up acquired resources. Stack unwinding is a mechanism used in C++ to properly terminate function execution during an exception throw.
Problem:
When an exception is thrown, control immediately transfers to catch blocks, and intermediate functions are "unwound": their destructors are called, but explicit calls to freeing functions may be missed (for example, if objects that automatically manage resources are not used).
Solution:
In C++, resource release should be entrusted to destructors rather than calling freeing functions manually. The RAII (Resource Acquisition Is Initialization) pattern is a clear way to make resource release automatic. During stack unwinding, the destructor will be called, and the resource will be released regardless of the exit path from the function.
Code Example:
#include <fstream> #include <stdexcept> void readFile(const std::string& filename) { std::ifstream file(filename); // Will open and close correctly even on exception if (!file.is_open()) { throw std::runtime_error("File cannot be opened"); } // ... read file } // file will close even on exception
Key Features:
If there is delete ptr; in the catch block, is that enough to clean up memory?
No, if an exception occurs between memory allocation and the catch block, the memory may not be cleaned up. It's better to use std::unique_ptr or put delete in the destructor.
Code Example:
void foo() { int* data = new int[10]; // ... throw std::runtime_error("fail"); delete[] data; // won't be called on exception }
Can stack unwinding skip calling the destructor for an object allocated on the stack?
No, all local objects (not destructed before the exception throw point) will be destroyed in the reverse order of their creation, destructors will be called reliably.
Can I use goto or longjmp to exit from the try block and expect destructors to be called?
No. C++ guarantees destructor calls only during stack unwinding due to an exception, not due to incorrect flow control (goto, setjmp/longjmp).
A programmer allocates memory using new, handles exceptions by freeing memory in the catch block, but forgets about other exit paths from the function.
Pros:
Cons:
std::unique_ptr and RAII classes are used for all resources, and release does not depend on try/catch.
Pros:
Cons: