C++ Memory Management


Memory management in C++ is one of the most important topics for mastering efficient and safe programming. Unlike many high-level languages, C++ gives you full control over how memory is allocated, used, and released. This control comes with great flexibility, but also with responsibility. Mismanaging memory can cause program crashes, memory leaks, or undefined behavior.

What is Memory Management in C++?

Every program you write in C++ uses memory to store data and instructions. The memory used by a program is generally divided into several parts:

  • Stack Memory – Used for storing local variables and function calls.

  • Heap Memory – Used for dynamic memory allocation during runtime.

  • Static Memory – Stores global and static variables.

  • Code Segment – Contains the compiled machine code of your program.

When your program runs, memory is automatically assigned to some variables (like local ones), while in other cases you may need to manually allocate and free memory using pointers.

Static and Dynamic Memory Allocation

In C++, there are two ways to allocate memory:

Static Memory Allocation

In static allocation, the size of memory is fixed at compile time. Local variables and arrays declared inside functions are examples of static allocation.

Example:

int num = 10;
int marks[5];

Here, the memory for num and marks is automatically allocated and freed when the function ends.

Dynamic Memory Allocation

Dynamic memory is allocated at runtime using operators like new and delete. This gives you flexibility to decide how much memory your program needs while it’s running.

Example:

int *ptr = new int;  // allocate memory for one integer
*ptr = 25;
cout << *ptr;
delete ptr;          // free memory

In this example:

  • new int allocates memory for one integer on the heap.

  • delete ptr releases the memory once it’s no longer needed.

Using new and delete Operators

C++ introduced new and delete to simplify memory management compared to C’s malloc() and free() functions.

Allocating Memory

int *num = new int(100);   // initialize value while allocating
cout << *num;

Releasing Memory

delete num;  // frees memory allocated for num
num = nullptr; // always good practice

Assigning nullptr ensures that the pointer doesn’t point to invalid memory after deletion.

Allocating Memory for Arrays

You can allocate memory for arrays dynamically using the same new operator, followed by array brackets.

Example:

int *arr = new int[5];  // dynamically allocate an array of 5 integers
for (int i = 0; i < 5; i++) {
    arr[i] = (i + 1) * 10;
}
for (int i = 0; i < 5; i++) {
    cout << arr[i] << " ";
}
delete[] arr;  // release the entire array memory

Using delete[] instead of delete is mandatory for arrays, otherwise only the first element gets released.

Memory Leaks and How to Avoid Them

A memory leak happens when dynamically allocated memory is never released. Over time, this can cause your program to consume more and more memory, slowing down or crashing the system.

Example of memory leak:

int *p = new int(50);
// memory allocated but not deleted

To prevent this, always pair every new with a corresponding delete:

delete p;
p = nullptr;

Setting the pointer to nullptr after deleting helps avoid dangling pointers, which occur when a pointer still references freed memory.

Dangling Pointers

A dangling pointer points to memory that has been freed or deallocated. Accessing it can cause crashes or unpredictable results.

Example:

int *ptr = new int(20);
delete ptr;  // memory released
*ptr = 30;   // dangerous: ptr is now dangling

To avoid this, always assign nullptr after deleting:

delete ptr;
ptr = nullptr;

Using malloc() and free() in C++

C++ supports the traditional C functions malloc() and free() for compatibility, though new and delete are preferred.

Example:

int *p = (int*)malloc(sizeof(int));
*p = 40;
cout << *p;
free(p);

However, unlike new, malloc() does not call constructors for objects, and free() does not call destructors. That’s why new and delete are safer for C++ objects.

Memory Management for Objects

You can also allocate memory for class objects dynamically.

Example:

class Student {
public:
    string name;
    int age;
    Student(string n, int a) {
        name = n;
        age = a;
    }
    void display() {
        cout << name << " - " << age << endl;
    }
};

int main() {
    Student *s1 = new Student("Aarushi", 20);
    s1->display();
    delete s1;  // release object memory
}

When you use delete, the object’s destructor is called automatically, ensuring safe cleanup.

Dynamic 2D Arrays in C++

You can create a two-dimensional array dynamically by using pointers to pointers.

Example:

int rows = 3, cols = 4;
int **matrix = new int*[rows];
for (int i = 0; i < rows; i++) {
    matrix[i] = new int[cols];
}

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        matrix[i][j] = i + j;
        cout << matrix[i][j] << " ";
    }
    cout << endl;
}

// free memory
for (int i = 0; i < rows; i++) {
    delete[] matrix[i];
}
delete[] matrix;

This technique is useful for working with tables, matrices, and grids dynamically.

Smart Pointers in Modern C++

Modern C++ introduced smart pointers to automate memory management and reduce manual errors.
These are available in the <memory> header.

Types of smart pointers:

  • unique_ptr – Owns a single object exclusively.

  • shared_ptr – Allows multiple pointers to share ownership.

  • weak_ptr – References a shared object without owning it.

Example using unique_ptr:

#include <memory>
int main() {
    unique_ptr<int> num = make_unique<int>(10);
    cout << *num;
}

Smart pointers automatically free memory when the object goes out of scope.

Summary of C++ Memory Management

  • Memory can be allocated statically or dynamically.

  • Use new and delete for dynamic allocation.

  • Always free unused memory to prevent memory leaks.

  • Avoid dangling pointers by assigning nullptr.

  • Prefer smart pointers for safer memory management.

  • malloc() and free() exist for compatibility but are not ideal for C++ objects.


Practice Questions

  1. Write a program to allocate memory for a single integer using new, assign a value, and then release it using delete.

  2. Create a program to dynamically allocate memory for an integer array, take user input, and print all elements.

  3. Write a C++ program that demonstrates a memory leak, then modify it to fix the leak using delete.

  4. Implement a program that dynamically allocates memory for a string using new char[] and displays it.

  5. Write a program to allocate and free a two-dimensional array (matrix) dynamically using pointers.

  6. Create a C++ class Student with dynamic memory allocation for storing the student’s name. Demonstrate proper use of the destructor to release memory.

  7. Implement a program that shows the difference between malloc()/free() and new/delete.

  8. Build a small program using unique_ptr that allocates memory for an integer and prints its value.

  9. Write a function that dynamically allocates an array, returns its pointer, and releases it in the main function.

  10. Create a program that allocates memory for 3 objects of a class using new[], initializes them, and deletes them using delete[].


Try a Short Quiz.

coding learning websites codepractice

No quizzes available.

Go Back Top