CLOSE

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 variables
  • delete[] 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.