Dynamic Memory Allocation in C++

This article covers dynamic memory allocation in C++. We will learn the use of new and delete operators.

Memory Allocation in C++

Memory architecture for a C++ program includes

  • Code Segment: This segment contains the executable code of the program.
  • Data Segment: It contains the global and static variables of the program.
  • Stack: It is the part of memory used for static memory allocation. The normal variables in a function are allocated stack space during compilation.
  • Heap: Also known as the free store, it is the unused part of memory. It is used to dynamically allocate memory at runtime.

Static Memory Allocation in C++

In static memory allocation, memory is allocated and deallocated by the compiler on its own. We need to define the required size of memory at the time of compilation.

Dynamic Memory Allocation in C++

In dynamic memory allocation, memory is allocated during runtime. But, in this case, it is the responsibility of a programmer to deallocate the dynamically allocated memory when it’s no longer in use. Otherwise, it leads to memory leaks.

Uses of Dynamic Memory Allocation

  • There are times when we do not know in advance the amount of memory required to store some data. Using dynamic memory allocation, we can allocate memory of variable size at runtime.
  • It provides flexibility to the programmer. Programmers can allocate and deallocate memory as and when needed.

In C, we use malloc() and calloc() functions to dynamically allocate memory. To deallocate that memory, we use free(). These functions are supported in C++ as well. But, it is suggested to avoid using these functions in C++.
C++ provides two unary operators, new and delete, to dynamically allocate and deallocate memory efficiently.

New Operator in C++

New operator serves requests to allocate memory on the heap. It allocates the memory if enough memory is available. Then, it returns the address of the newly allocated and initialised memory space to the pointer variable.

For any data type, syntax to dynamically allocate memory is

pointer_variable = new data_type;

Here,

  • pointer_variable is a pointer whose type is data_type.
    data_type can either be any built-in data type including array or any user-defined data type like structure and class.

For example,

int *ptr = NULL;	//pointer ptr initialised with NULL
ptr = new int;		//requests memory

This can be combined and written in a single line as

int *ptr = new int;

Syntax to initialise memory with new operator:

pointer_variable = new data_type(value);

For example,

int *ptr = new int(10);

Note that pointers play an important role in dynamic memory allocation.

If enough memory is not available in the heap

If the heap does not have enough memory, an exception of type std::bad_alloc is thrown indicating request failure. So, we use ‘nothrow’ with the new operator as then the new operator returns NULL.

It is a good practice to check if the returned pointer is NULL.

int *ptr = new(nothrow) int;
if (!ptr) {
  cout<< “Failed! Memory not available.”<<endl;
  exit(1);
}

Delete Operator in C++

Delete operator frees the dynamically allocated memory when it’s no longer in use.

Syntax

delete pointer_variable;		//Releases memory pointed to by pointer_variable

Example of dynamic memory allocation in C++

#include <iostream>
using namespace std;

int main() {
  int *ptr = new(nothrow) int;
  
  if(!ptr){
      cout<<"Failed! Memory not available."<<endl;
      exit(1);
  }
  
  *ptr = 100;
  
  cout<<"Value = "<<*ptr;
  
  delete ptr;
  return 0;
}

Output

Value = 100

C++ Dynamic Memory Allocation for Arrays

Many times, we are not sure of the size of an array until runtime. Dynamic memory allocation serves the purpose in such situations. It makes memory management more efficient.

Syntax to allocate a block of memory for an array:

pointer_variable = new data_type[size];

For a multidimensional array of size m x n,

pointer_variable = new data_type[m][n];

Syntax to deallocate the memory occupied by any array:

delete [ ] pointer_variable;

Example of dynamic memory allocation for arrays in C++

#include <iostream>
using namespace std;

int main() {
  int *ptr = new(nothrow) int[10];
  
  if(!ptr){
      cout<<"Failed! Memory not available."<<endl;
      exit(1);
  }
  
  for(int i=0; i<10; i++){
      ptr[i]=i+1;
  }
  
  for(int i=0; i<10; i++){
      cout<<ptr[i]<<" ";
  }
  
  delete [] ptr;
  return 0;
}

Output

1 2 3 4 5 6 7 8 9 10

Dynamic Memory Allocation for Objects

We can dynamically allocate memory to objects also.

Example of dynamic memory allocation for objects in C++

#include <iostream>
using namespace std;

class Test {
    public:
    Test() {
        cout<<"Constructor"<<endl;
    }
    ~Test() {
        cout<<"Destructor"<<endl;
    }
};
int main() {
  Test *t = new Test[3];
  delete [] t;
  return 0;
}

Output

Constructor
Constructor
Constructor
Destructor
Destructor
Destructor

Observe that since we allocated an array of three Test objects, constructor is called thrice. Similarly, while freeing these objects, destructor is also called thrice.

Dangling Pointer

A dangling pointer is a pointer that points to a memory address that has been freed (or deallocated).

Summary

In this article, we learnt how to dynamically allocate memory in C++ using examples. Firstly, we learnt the types of memory allocation. Then we discussed the uses of dynamic memory allocation.

C++ provides new and delete operators to dynamically allocate and deallocate memory respectively. Then, we discussed dynamic memory allocation for arrays and objects.