03 — Object Lifetime, Stack, Heap, and RAII
03 — Object Lifetime, Stack, Heap, and RAII
Core Idea
C++ is a lifetime language. To write good C++, you must know when objects are created, when they are destroyed, and who owns resources.
Stack Lifetime
Objects created in a scope are destroyed automatically when the scope ends.
void f() {
std::string name = "Ada";
} // name is destroyed here
This is deterministic cleanup.
Heap Lifetime
Heap objects live until explicitly released or until their owner releases them.
Old style:
User* user = new User("Ada");
delete user;
Modern style:
auto user = std::make_unique<User>("Ada");
The unique_ptr deletes the object automatically.
RAII
RAII means Resource Acquisition Is Initialization.
A resource is acquired in a constructor and released in a destructor.
Resources include:
- memory,
- files,
- sockets,
- locks,
- database connections,
- GPU handles,
- OS handles.
Example:
void write_file() {
std::ofstream file("out.txt");
file << "hello\n";
} // file closes automatically here
Why RAII Matters
RAII handles cleanup even when exceptions or early returns happen.
void work() {
std::lock_guard<std::mutex> lock(m);
// mutex is unlocked automatically when lock leaves scope
}
Destructors
A destructor runs when an object dies.
class FileHandle {
public:
FileHandle() { /* acquire */ }
~FileHandle() { /* release */ }
};
Modern code usually avoids custom destructors by using standard library types that already manage resources.
Common Lifetime Bugs
Dangling Reference
const std::string& bad() {
std::string s = "dead";
return s; // dangling reference
}
Use After Free
User* p = new User{};
delete p;
p->name(); // invalid
Returning Pointer to Local
int* bad() {
int x = 42;
return &x; // invalid after return
}
Rule of Thumb
If a resource needs cleanup, put it inside an object whose destructor performs the cleanup.
Quick Self-Test
You should be able to explain:
- When does a stack object get destroyed?
- Why is RAII safer than manual cleanup?
- Why is returning a reference to a local variable invalid?
- Why should
newanddeletebe rare in modern C++?