Dynamic Memory Allocation
Master dynamic memory allocation with new and delete operators to create variables and arrays at runtime on the heap
Learn how to dynamically allocate memory at runtime using the new and delete operators, giving you control over when memory is allocated and freed.
A Simple Example
#include <iostream>
int main() {
// Stack allocation (automatic)
int stackVar{42}; // Created on stack, dies at end of scope
// Heap allocation (dynamic)
int* heapVar{new int{42}}; // Created on heap, persists until deleted
std::cout << "Stack: " << stackVar << "\n";
std::cout << "Heap: " << *heapVar << "\n";
delete heapVar; // MUST free the memory!
heapVar = nullptr; // Good practice
return 0;
} // stackVar dies here, heapVar was already deleted
Breaking It Down
The new Operator
- What it does: Allocates memory on the heap and returns a pointer to it
-
Syntax:
int* ptr{new int{42}};for single values,int* arr{new int[10]};for arrays -
Remember: Every
newmust be paired with adelete, or you will leak memory - Unlike stack variables, heap memory persists until you explicitly delete it
The delete Operator
-
What it does: Frees memory that was allocated with
new -
Syntax:
delete ptr;for single objects,delete[] arr;for arrays -
Critical rule: Match
newwithdeleteandnew[]withdelete[] - Good practice: Set pointer to nullptr after deletion to avoid dangling pointers
Stack vs Heap Memory
- Stack: Fast, automatic, limited size (usually 1-8 MB), variables die when scope ends
- Heap: Slower, manual management, much larger, memory persists until you delete it
- Use stack for: Small, fixed-size data with known lifetime
- Use heap for: Large data, variable sizes, data that needs to outlive the current scope
Dynamic Arrays
- What they are: Arrays whose size can be determined at runtime
-
Syntax:
int* arr{new int[size]};where size can be a variable -
Must use:
delete[] arr;to free the entire array properly -
Remember: In modern C++, prefer
std::vectorfor dynamic arrays - it manages memory automatically
Why This Matters
- Stack-allocated variables have fixed sizes known at compile time and limited lifetimes. They automatically die when they go out of scope.
- Dynamic memory allocation lets you create data structures of variable size at runtime, control exactly when memory is freed, implement resizable arrays and complex data structures, and efficiently manage large amounts of data that would overflow the limited stack space.
Critical Insight
When you allocate with new[], you MUST delete with delete[]. Using just delete instead of delete[] on an array causes undefined behavior and potential memory leaks. Similarly, never use delete[] on a non-array allocation!
Think of it like this: new[] and delete[] work as a pair for arrays, while new and delete work as a pair for single objects. Mixing them is like trying to unlock a door with the wrong key - it might seem to work sometimes, but it is dangerous and incorrect.
Best Practices
Always pair new with delete: Every new needs exactly one delete, and every new[] needs exactly one delete[]. No exceptions.
Set pointers to nullptr after deletion: After calling delete ptr;, immediately set ptr = nullptr; to prevent accidentally using a dangling pointer.
Prefer modern alternatives: Use std::vector instead of new[] for arrays, and std::unique_ptr or std::shared_ptr for automatic memory management.
Check allocation success: In critical systems, check if new returns nullptr (when using std::nothrow) to handle allocation failures gracefully.
Common Mistakes
Forgetting to delete: Memory leaks happen when you allocate with new but never call delete. This memory is lost for the lifetime of your program.
Using delete instead of delete[]: Arrays allocated with new[] must be freed with delete[]. Using just delete causes undefined behavior and memory leaks.
Deleting the same memory twice: Double deletion causes undefined behavior and crashes. Always set pointers to nullptr after deletion.
Using memory after delete: Accessing a deleted pointer (dangling pointer) causes undefined behavior. Always set pointers to nullptr after deletion.
Not checking for allocation failure: While rare, new can fail. Use std::nothrow and check for nullptr in critical systems, or use exceptions.
Debug Challenge
This program allocates an array but has a bug when freeing it. Click the highlighted line to fix it:
Quick Quiz
- What is the difference between
newandnew[]?
- What happens if you forget to delete dynamically allocated memory?
- Where is dynamically allocated memory stored?
Practice Playground
Time to try out what you just learned! Play with the example code below, experiment by making changes and running the code to deepen your understanding.
Output:
Error:
Lesson Progress
- Fix This Code
- Quick Quiz
- Practice Playground - run once