Memory · Memory & ownership
Stack vs heap
Separate where an owner lives from how long its object lives.
Think in lifetimes first.
Ordinary local objects usually have automatic storage duration: they are destroyed when their scope exits. Dynamically allocated objects can outlive the function that creates them and need an owner to release them. “Stack” and “heap” are useful implementation terms; C++ specifies the lifetimes and storage durations.
A local owner, a dynamic object.
owner is an automatic unique_ptr. The integer it owns is dynamically allocated. Leaving this scope destroys owner, whose destructor releases the integer. Dynamic allocation does not mean the object must live for the entire program.
{
int local = 4;
auto owner = std::make_unique<int>(9);
std::cout << local + *owner;
} // both integers are goneThe pointer and target have separate lifetimes.
The owner itself is local. Its target is a distinct dynamically allocated object. RAII connects their cleanup; merely storing an address in a raw pointer does not create that contract.
- Local owner
- automatic duration
- int: 9
- dynamic duration
- Local owner leads to int: 9 (owns)
Return an owner, not a dangling address.
Returning a unique_ptr transfers ownership of the dynamic integer to the caller. The integer stays alive under the returned owner. The creating function ending is different from the owned integer being destroyed.
std::unique_ptr<int> makeScore() {
return std::make_unique<int>(42);
}
auto score = makeScore();
std::cout << *score;An address cannot extend a local’s lifetime.
If a function returns the address of its ordinary local int, that int’s lifetime still ends when the function returns. Dereferencing the returned pointer is unsafe. Returning the int by value or returning an owning smart pointer expresses a valid result lifetime.
Further reading
Trusted resources for the rules and APIs discussed in this guide.