What is a memory leak?
Allocated heap memory never freed—program consumes more RAM over time.
Master C++ dynamic memory with comprehensive examples of stack vs heap memory, new/delete operators, memory management, smart pointers, and practical applications. Learn efficient memory allocation techniques.
Automatic allocation
Dynamic allocation
Memory safety
Prevention & detection
Stack memory is automatic; heap memory is manual (or smart). Learn allocation, deallocation, leaks, and why RAII and smart pointers are the modern default.
Memory questions dominate C++ interviews. Employers expect you to prefer smart pointers over raw new/delete in new code.
C++ provides two main types of memory: stack and heap. Understanding the difference between them is crucial for writing efficient, safe, and correct C++ programs. Dynamic memory management allows programs to allocate memory at runtime, providing flexibility but also requiring careful management.
Fast, automatic, LIFO structure
Flexible, manual management, global access
new/delete| Feature | Stack Memory | Heap Memory |
|---|---|---|
| Allocation Method | Automatic by compiler | Manual using new/malloc |
| Deallocation | Automatic when scope ends | Manual using delete/free |
| Access Speed | Very fast (direct CPU instructions) | Slower (requires pointer indirection) |
| Size Limit | Small (typically 1-8 MB) | Large (limited by OS/available RAM) |
| Memory Layout | Contiguous, LIFO structure | Fragmented, random access |
| Lifetime | Function/scope lifetime | Until explicitly freed |
| Flexibility | Fixed size at compile time | Dynamic size at runtime |
| Thread Safety | Each thread has its own stack | Shared across threads (requires synchronization) |
| Common Uses | Local variables, function calls, return addresses | Large data, dynamic arrays, objects with varying lifetime |
| Risk Factors | Stack overflow, use-after-return | Memory leaks, dangling pointers, fragmentation |
int x = 10; // stackint* p = new int(20);delete p; p=nullptr;int a[5] = {1,2,3,4,5};int* h = new int[5];delete[] h;int* p = new int;
*p = 7;int* q = new int(42);double* d = new double[3];delete q;delete[] d;int* r = new(nothrow) int[1000];int* p=new int(1);
// forgot deleteint* p=new int(1);
delete p;int* p=new int[10];
if (err) return;vector<int> v(10);p=new int(2); p=new int(3);auto sp=make_unique<int>(3);auto u = make_unique<Dog>();auto v = move(u);auto s1=make_shared<Cat>();
auto s2=s1;weak_ptr<Node> w = n;unique_ptr<FILE,Deleter> f;auto x=make_shared<int>(5);In modern C++, avoid manual memory management with raw new/delete. Instead, use smart pointers and RAII. Prefer stack allocation for small, short-lived objects. Use unique_ptr for exclusive ownership, shared_ptr only when shared ownership is truly needed, and weak_ptr to observe shared resources without ownership.
struct Node { int d; Node* next; };n->next=head; head=n;while(head){ auto t=head; head=head->next; delete t;}vector<int> v; v.push_back(1);v.reserve(100);int** g=new int*[n];| Practice | Bad Example | Good Example |
|---|---|---|
| Memory Allocation | int* arr = new int[n]; |
vector<int> arr(n); or unique_ptr<int[]> |
| Ownership Transfer | Resource* create() { return new Resource(); } |
unique_ptr<Resource> create() { return make_unique<Resource>(); } |
| Exception Safety | void process() { Resource* r = new Resource(); /* might throw */ delete r; } |
void process() { auto r = make_unique<Resource>(); /* exception safe */ } |
| Array Management | int** matrix = new int*[rows]; for(i) matrix[i] = new int[cols]; |
vector<vector<int>> matrix(rows, vector<int>(cols)); |
| Resource Cleanup | File* f = fopen(); /* ... */ fclose(f); |
unique_ptr<FILE, decltype(&fclose)> f(fopen(), &fclose); |
| Polymorphic Objects | Base* obj = new Derived(); delete obj; |
unique_ptr<Base> obj = make_unique<Derived>(); |
void process() {
int* ptr = new int[100];
if (errorCondition) return;
delete[] ptr;
}
unique_ptr: Exclusive ownershipshared_ptr: Shared ownershipweak_ptr: Non-owning observationIn modern C++ (C++11 and later), avoid raw new/delete. Use smart pointers for ownership, stack allocation for local variables, and standard containers for collections. Implement RAII for all resources. Let the compiler and standard library handle memory management whenever possible.
Mastering dynamic memory is crucial for advanced C++ programming. Practice with custom allocators, study memory profiling tools, explore multi-threaded memory management, and learn about memory-mapped files. Understanding memory at a deep level will make you a more effective systems programmer.
Allocated heap memory never freed—program consumes more RAM over time.
unique_ptr for exclusive ownership; shared_ptr when multiple owners must share lifetime.
Both allocate heap memory; new calls constructors, malloc does not—prefer new/smart pointers in C++.