CS310 — new, delete, and Managing the Heap
Static memory is managed by the compiler. Dynamic memory is managed by you — allocate with new, free with delete.
Why do we need dynamic memory at all?
new OperatorAllocate memory on the heap at runtime
new works: It asks the OS for memory from the heap, and returns the address (pointer) of that memory. The pointer itself lives on the stack, but the data lives on the heap.
new throws a std::bad_alloc exception and the program terminates (unless you catch it).
Allocate an array based on user input
delete OperatorFree heap memory when you're done with it
new must have a matching delete. Every new[] must have a matching delete[]. Miss one? Memory leak. Mix them up? Undefined behavior.
delete a pointer to a stack variable — that's undefined behavior and will likely crash.
new checks out a hotel room. delete checks out. If you forget to check out, you're still paying (memory leak). If you check out twice, chaos (double free).
Allocate → Use → Free — step by step
A pointer to memory that has been freed — the most dangerous bug
p = nullptr; right after delete p;. Then check if (p != nullptr) before using it.
Allocated memory that can never be freed — it's gone forever
delete before the pointer goes out of scopenew must have exactly one matching delete. No more (double free), no less (leak). This is why modern C++ prefers smart pointers (unique_ptr, shared_ptr).
What you can and cannot return — and why
result lives on the stack. When the function returns, that stack frame is destroyed. The pointer now points to freed memory — a dangling pointer!
delete[] it. The function allocates on the heap, returns the pointer, and the caller is responsible for freeing it.
Allocate in function, use in caller, free when done
new doesn't always call delete. Here, reverse() allocates but main() frees. The "owner" of the memory is whoever holds the pointer and is responsible for freeing it.
A decision guide for memory allocation
Which code snippets have memory leaks?
Six pitfalls to avoid
std::unique_ptr and std::shared_ptr — they automatically call delete when the pointer goes out of scope. Zero leaks, zero dangling pointers.
This function has a memory management error
The future: automatic memory management without garbage collection
Single owner. Deleted when owner goes out of scope. Can't be copied, only moved.
Reference counted. Multiple owners. Deleted when last owner is destroyed.
Non-owning observer. Doesn't prevent deletion. Used to break circular references.
unique_ptr by default. Use shared_ptr only when you truly need shared ownership. Use raw new/delete only when you understand why you need it.
The rules to live by
new Tnew T[n]delete pdelete[] pp = nullptrif (p)unique_ptrmake_uniquenew needs a deletenew[] needs a delete[]nullptr after deleteFor each scenario, choose the right allocation strategy
i used in a for loopnew allocate?new int[10]?How many bytes are leaked?