Dynamic allocation allows us to request memory during runtime using pointers. This is essential when we don't know the amount of memory we need in advance – such as for user input, dynamic arrays, trees, or graphs.
Using new
and delete
Allocating Single Variables
To dynamically allocate memory for a single variable:
int* ptr = new int; // Allocates memory for one int
*ptr = 42; // Assign value
std::cout << *ptr; // Output: 42
delete ptr; // Deallocate memory
You can initialize during allocation:
int* ptr = new int(100); // Initializes with 100
Allocating Arrays Dynamically
When the size is unknown as compile-time:
int* arr = new int[5]; // Allocate array of 5 integers
for (int i = 0; i < 5; ++i) arr[i] = i;
delete[] arr; // Use delete[] for arrays
⚠️ Important:
delete
is for single variablesdelete[]
is for arrays
Common Pitfalls
❌ Dangling Pointers
Accessing memory after it's freed:
int* p = new int(10);
delete p;
*p = 20; // Undefined behavior!
Solution: Set pointer to nullptr
after deleting:
delete p;
p = nullptr;
❌ Memory Leaks
Forgetting to delete
allocated memory:
void leak() {
int* ptr = new int(5); // Memory not released
} // Leak occurs when ptr goes out of scope
Best practice: Every new
must have a corresponding delete
.
❌ Double delete
int* p = new int(5);
delete p;
delete p; // Error: double free
Null Pointers and Safety Checks
Use nullptr
(C++11)
int* ptr = nullptr;
if (ptr == nullptr) {
std::cout << "Pointer is null\n";
}
This replaces the older, ambiguous NULL
or 0
.
Safe Deletion Pattern
if (ptr) {
delete ptr;
ptr = nullptr;
}
This ensures you never delete
a null or already deleted pointer.