Back to C++
2026-02-186 min read

dynamic memory allocation (C++)

Learn dynamic memory allocation (C++) step by step with clear examples and exercises.

Why This Matters

Dynamic memory allocation is a fundamental aspect of C++ programming that offers flexibility and efficiency in managing memory at runtime. It allows us to create programs that can adapt to varying data sizes during execution, avoiding hard-coded memory allocations which would limit the scalability of our applications. In real-world scenarios, dynamic memory allocation helps manage memory more efficiently and avoid common issues like segmentation faults due to insufficient memory.

Dynamic memory allocation enables us to create programs that can handle data of different sizes without knowing them at compile time. This makes our applications more adaptable and scalable, as they can adjust their memory usage based on the input provided by the user or the environment.

Prerequisites

Before diving into dynamic memory allocation, you should have a solid understanding of:

  1. C++ basics (variables, data types, operators, control structures)
  2. Pointers and arrays in C++
  3. The standard I/O library (``)
  4. Basic file I/O operations (``)
  5. Understanding of classes and objects in C++
  6. Familiarity with constructors, destructors, and copy constructors
  7. Exception handling (` and `)
  8. Understanding the difference between stack and heap memory

Core Concept

Allocating Memory Dynamically

Dynamic memory allocation is achieved using the new and delete operators in C++. Here's a simple example:

int *ptr = new int; // allocate memory for an integer variable
*ptr = 42; // assign a value to the allocated memory
std::cout << *ptr << endl; // print the value stored in the memory
delete ptr; // deallocate the memory when it's no longer needed

In this example, we create a pointer ptr that points to an integer variable. We then allocate memory for an integer using new, assign a value to the allocated memory, print the value, and finally free the memory using delete.

Dynamic Arrays

Dynamic arrays can be created using new[] and delete[]:

int *arr = new int[10]; // allocate an array of 10 integers
arr[5] = 42; // assign a value to the fifth element of the array
std::cout << arr[5] << endl; // print the value stored in the fifth element
delete[] arr; // deallocate the memory when it's no longer needed

Allocating Objects with Constructors and Destructors

When allocating objects using new, their constructors are called automatically. Similarly, when deleting an object, its destructor is called:

MyClass *obj = new MyClass(42); // allocate memory for a MyClass object and call its constructor with argument 42
// use the object as needed...
delete obj; // deallocate the memory and call its destructor

Smart Pointers

To avoid common mistakes like memory leaks, C++ provides smart pointers (such as std::unique_ptr, std::shared_ptr, and std::weak_ptr) that automatically manage memory allocation and deallocation for us. These smart pointers offer additional benefits such as exception safety, automatic resource management, and improved performance in some cases.

Exception Safety with New and Delete

When an exception is thrown during the construction of an object using new, the memory allocated for that object might not be properly deallocated if the exception isn't caught. To handle this issue, it's recommended to use a helper function called std::launder to safely cast the exception-thrown pointer to a valid one before deleting it:

try {
MyClass* obj = new MyClass(42);
// ...
} catch (...) {
MyClass* valid_ptr = std::launder<MyClass*>(std::current_exception());
delete valid_ptr;
}

Worked Example

Let's create a simple program that reads an integer from the user, dynamically allocates memory for an array, stores the input values, and then calculates their sum:

#include <iostream>
#include <vector>

class MyClass {
public:
MyClass(int value) : m_value(value) {}
int getValue() const { return m_value; }

private:
int m_value;
};

int main() {
std::cout << "Enter the number of elements: ";
int n;
std::cin >> n;

std::vector<MyClass> arr(n); // allocate a vector of MyClass objects

std::cout << "Enter " << n << " integers for each object's constructor:\n";
for (int i = 0; i < n; ++i) {
int value;
std::cin >> value;
arr[i] = MyClass(value);
}

int sum = 0;
for (const auto& obj : arr) {
sum += obj.getValue();
}

std::cout << "The sum of the entered integers is: " << sum << endl;

return 0;
}

In this example, we use a std::vector to dynamically allocate an array of MyClass objects. This approach offers better exception safety compared to using raw pointers and manual memory management.

Common Mistakes

  1. Forgetting to initialize dynamically allocated memory: It's essential to set all dynamically allocated memory to a known state before using it, such as zeroing out an array or setting pointers to null.
  1. Not checking for errors when allocating memory: Always check if the allocation was successful by testing whether the pointer returned by new is not nullptr.
  1. Forgetting to deallocate memory: Failing to free dynamically allocated memory leads to memory leaks, which can cause performance issues and crashes in your program.
  1. Double-freeing memory: Attempting to free the same memory twice leads to undefined behavior and might cause a segmentation fault.
  1. Using deleted or uninitialized pointers: Trying to access memory through a pointer that has been deleted or is not initialized can result in a runtime error.
  1. Not using smart pointers for better memory management
  2. Ignoring exception safety when using new and delete

Practice Questions

  1. Write a program that dynamically allocates an array of characters and reads a line from the user, storing it in the array. Then, print out the reversed version of the entered line.
  1. Implement a dynamic memory-based implementation of a stack using C++. Use smart pointers for better memory management.
  1. Create a program that dynamically allocates a 2D array (vector of vectors) to store integers and allows the user to input, display, and delete rows as needed.
  1. Implement a dynamic memory-based implementation of a queue using C++. Use smart pointers for better memory management.
  1. Write a program that reads a file line by line, dynamically allocates memory for each line, stores the content in the allocated memory, and then prints out the total number of words in all lines.

FAQ

Q: Why should I use dynamic memory allocation instead of static arrays?

A: Dynamic memory allocation allows you to create programs that can adapt to varying data sizes during execution, making your programs more flexible and efficient for handling data of different sizes. In contrast, static arrays have a fixed size that must be known at compile-time.

Q: What is the difference between new and malloc()?

A: Both new and malloc() are used to allocate memory dynamically in C++ and C, respectively. However, new provides additional functionality like constructing objects with their default or custom constructors, while malloc() only allocates raw memory without any object initialization. Additionally, new automatically deallocates the memory when the object goes out of scope, whereas you must manually call free() for malloc().

Q: When should I use smart pointers instead of traditional pointers?

A: Smart pointers are recommended over traditional pointers when dealing with dynamic memory allocation to avoid common mistakes like memory leaks and double-freeing. They provide automatic memory management, making the code easier to write, read, and debug.

Q: Why is it important to check for errors when allocating memory using new?

A: Checking for errors when allocating memory using new ensures that the allocation was successful and helps prevent runtime errors caused by null pointers or insufficient memory. It's a good practice to always check if the pointer returned by new is not nullptr.

Q: What are some common mistakes to avoid when working with dynamic memory allocation in C++?

A: Some common mistakes to avoid include forgetting to initialize dynamically allocated memory, forgetting to deallocate memory, double-freeing memory, using deleted or uninitialized pointers, and ignoring exception safety when using new and delete. It's essential to follow best practices and use smart pointers for better memory management.

dynamic memory allocation (C++) | C++ | XQA Learn