Dynamic Memory Allocation in C++

Learn via video course
FREE
View all courses
C++ Course: Learn the Essentials
C++ Course: Learn the Essentials
by Prateek Narang
1000
5
Start Learning
C++ Course: Learn the Essentials
C++ Course: Learn the Essentials
by Prateek Narang
1000
5
Start Learning
Topics Covered

Overview

The process of allocating or de-allocating a block of memory during the execution of a program is called Dynamic Memory Allocation. The operators new and delete are utilized for dynamic memory allocation in C++ language, new operator is used to allocate a memory block, and delete operator is used to de-allocate a memory block which is allocated by using new operator.

C++ Program Memory Management

When we run a C++ program on our machine, it requires some space to store its instructions (statements), local variables, global variables, and various other functions in C++. This space required to run a C++ Program is known as memory in computers.

There are two types of memory in our system, Static Memory and Dynamic Memory.

  • Static Memory: It is a constant space allocated by the operating system during the compile time of a C++ program and it internally uses stack data structure to manage the static memory allocation. We can't reallocate the space consumed by the program until its execution is over.

  • Dynamic Memory: It is the memory that can be allocated or de-allocated by the operating system during the run-time of a C++ program. It is more efficient than static memory because we can de-allocate and reuse our memory during the run-time of our program.

The memory used by a C++ program can be divided further into four parts:

  1. Run-time Stack (Static Memory)
  2. Static Data Memory (for Global and Static Variables)
  3. Instructions / Statements (Static Memory)
  4. Heap (Dynamic Memory)

Types of Memory

The Stack memory

  • Our operating system allocates a constant space during compile-time of a C++ program, this space is known as Stack memory.
  • Stack memory is used to hold functions, different variables, and local statements that exist in the function definition.
  • Stack is a part of the static memory in our system and it constitutes the majority of our system's static memory.

The Heap Memory

  • Heap memory is also known as the dynamic memory in our system. It can be thought of as a large block of memory that is expandable and shrinkable during the execution of a program.
  • Allocation and De-allocation of memory blocks during the execution of a program can be done using new and delete operators in C++ (these operators are discussed later in the article).
  • Heap memory can be expanded as long as we do not exhaust the machine memory itself. It is not good from a programming perspective to completely use the machine memory to avoid errors, thus we must use the heap memory carefully.

Types of Memory Allocation

1. Static Memory Allocation in C++ (Compile-time Memory Allocation)

  • When memory is allocated at compile-time, it is referred to as Static Memory Allocation.
  • A fixed space is allocated for the local variables, function calls, and local statements, that can not be changed during the execution of the program.
  • We can not allocate or de-allocate a memory block once the execution of the program starts.
  • We can't re-use the static memory while the program is running. As a result, it is less effective.

2. Dynamic Memory Allocation in C++ (Run-time Memory Allocation)

  • When memory is allocated or de-allocated during run-time, it is referred to as Dynamic Memory Allocation in C++.
  • A variable space is allocated that can be changed during the execution of the program.
  • We use dynamic/heap memory to allocate and de-allocate a block of memory during the execution of the program using new and delete operators.
  • We can re-use our heap memory during the run-time of our program. As a result, it is highly effective.

Why Dynamic Memory Allocation?

There were some drawbacks of stack memory or static memory allocation, like the space allocated for the stack can not be expanded during the execution of a C++ program or we can't keep variables in the program till the time we want. So, to overcome these drawbacks, we use the Dynamic Memory Allocation concepts.

Dynamic Memory Allocation is also a very essential topic in the field of data structures, and it is utilized practically in all data structures. For example, dynamic arrays, linked lists, queues, trees, stack, etc. uses DMA to allocate and de-allocate memory blocks during the execution of a C++ program.

How is it Different from Memory Allocated to Normal Variables?

The operating system uses static memory allocation for normal data-type variables and arrays, for example, int r;, double arr[10];, char name[20];, etc., the memory is automatically allocated at compile time and de-allocated when the function, block, or program finishes by the operating system.

The operating system uses dynamic memory allocation in C++ for dynamically allocated variables, for example, int* ptr = new int;, int* arr = new int[6];. Dynamically allocated memory does not get de-allocated until the program terminates. So, a programmer must de-allocate the memory, when it is no longer required. Memory leaks can occur when a programmer fails to de-allocate a dynamically allocated memory.

How is Memory Allocated/De-Allocated in C++?

In C Language, before allocating or de-allocating memory dynamically (at run-time), we have to include <stdlib.h> header file to use the library functions like malloc(), calloc(), realloc() and free().

In C++ Language, new and delete operators are pre-defined in the C++ Standard Library and don't require to include any library file for run-time allocation and de-allocation of memory blocks. Although we can use malloc(), calloc(), and other functions in C++ as well by adding the <stdlib.h> header file because of the backward compatibility of C++ with C Language. This article explains the new and delete operators of the C++ language. Visit Dynamic Memory Allocation in C - Scaler Topics to know more about DMA functions in C Language.

Dynamic Memory Allocation & De-allocation Criteria

1. Creating the Dynamic Space in Memory.

During the dynamic memory allocation in C++, first, we have to create a dynamic space (in the heap memory). We use the new operator to create a dynamic space.

2. Storing its Address in a Pointer

Once a dynamic space a created, we have to store the address of the allocated space in a pointer variable to access and modify the contents of the memory block.

3. Deleting the Allocated Space

Once the user does not require the memory block, we delete the allocated space using the delete operator to free up the heap memory.

The "new" operator in C++

The new operator in C++ is used to dynamically allocate a block of memory and store its address in a pointer variable during the execution of a C++ program if enough memory is available in the system.

Syntax for "new" operator:

  • ptr_var is a pointer, which stores the address of the type data_type.
  • Any pre-defined data types, like int, char, etc., or other user-defined data types, like classes, can be used as the data_type with the new operator.

Example C++ Program:

Output:

Explanation:

  • A memory block is allocated using the new operator and the address of the memory block has been stored in the ptr pointer.
  • (*ptr) represents the value at the allocated memory location. We have assigned 12 in the memory using *ptr = 12 expression.

Initializing Dynamic Memory

Syntax:

Example C++ program:

Output:

What Happens if the System's Memory Runs out During the Execution of the Program?

When there is insufficient memory in the heap segment during the run-time of a C++ program, the new request for allocation fails by throwing an exception of type std::bad alloc. It can be avoided using a nothrow argument with the new operator. When we use nothrow with new, it returns a NULL pointer. So, the pointer variable should be checked that is formed by new before utilizing it in a program.

Example:

The "delete" Operator in C++

The delete operator is used to de-allocate the block of memory, which is dynamically allocated using the new operator. Since, a programmer must de-allocate a block of memory, once it is not required in the program. So, we have to use the delete operator to avoid memory leaks and program crash errors, which occur due to the exhaustion of the system's memory.

Syntax:

Syntax to delete a single block of memory:

Syntax to delete an array of memory:

Example C++ Program:

Output:

(output garbage value is compiler dependent and will be different at each run)

Explanation:

  • A memory block for the stars pointer is allocated using the new operator and the address of the memory block has been stored in the stars pointer.
  • We have used the delete operator to de-allocate the memory pointed by the stars pointer, as it is no longer required in our program.
  • The memory is de-allocated but the stars pointer is still pointing to some garbage location in the memory. So, it will show garbage value if printed on the output screen. We have assigned NULL to the stars pointer in the end to avoid the situation of a dangling pointer.

Image Explanation: Dynamic Memory Allocation in C++

Dynamic Memory Allocation in C++ for Arrays

Allocating a Block of Memory Using the "new" Operator

The new operator can also be used to allocate a block of memory (an array) of any data_type.

Syntax:

Example

Standard Array Declaration vs Using the "new" Operator

The most significant distinction between standard arrays and a dynamically allocated array is that standard arrays are de-allocated by the online C++ compiler when the function execution finishes or it goes out of scope. While with dynamically allocated arrays, arrays always remain in the memory until either the programmer de-allocates them or the program execution finishes.

Syntax for normal array declaration:

Syntax for dynamically allocated array:

Example C++ Program with new operator:

Custom Input:

Output:

(output garbage values are compiler dependent and different at each run)

Explanation:

  • We have created a dynamically allocated array using the new operator.
  • Then, we have taken input for the array elements from the user and printed the array elements.
  • With the use of the delete operator on the array pointer arr, we have de-allocated the array memory. Now, the array location will contain garbage values as seen in the output.

Dynamic Memory Allocation in C++ for Objects

We can dynamically allocate memory for objects also. When we create an object of a class, a constructor function is invoked. Constructor is a member function of a class that is used to initialize the object. Also, when the object goes out of scope or gets de-allocated, a destructor function is invoked. Destructor is also a class member function that helps in knowing when the object's memory gets deleted.

We use pointers once more for allocating memory to objects.

Example C++ Program:

Output:

Explanation: We have created a class Animal with constructor and destructor member functions. In the main() function, we have created a dog object of class Animal using the new operator, which invokes the constructor function of the Animal class. When we have used the delete operator to de-allocate the dog object memory, the destructor function is invoked.

Comparison with "malloc()", "calloc()", and "free()" Functions of C.

First, let's see the small definitions of malloc(), calloc(), and free() library function to get a basic understanding of the functions.

C FunctionsDefinitionSyntax
malloc()It is used to allocate memory of the argument's size (in bytes) and returns a void pointer to the allocated pointer's first byte.(cast-data-type *)malloc(size-in-bytes)
calloc()It is used to allocate space as an array of elements, it also initializes all the elements with 0 and returns a void pointer.(cast-data-type *)calloc(num, size-in-bytes)
free()It is used to clear the allocated space (de-allocate) from the heap memory.free(ptr)

Note: The malloc() and the calloc() function returns a void pointer, so we have to typecast them into the required data types before using the allocated memory.

"new" vs "malloc()" and "calloc()"

The new operator has a similar working as malloc() and calloc() functions because these all are used to allocate memory during the execution of a C/C++ program but, when the new operator is used with objects it invokes the constructor function of the class, while malloc() and calloc() doesn't invoke the constructor function.

Example C++ Program:

Output:

Explanation: We can see that, when an object dog was created using the new operator, the constructor is invoked. Also, when we have created an array of Animal class (dogs) with 5 elements, the default constructor is invoked 5 times (constructor is invoked 6 times in total). Whereas, when an object was created using the malloc() or calloc() function, the constructor function is not called.

"delete" vs "free()"

The delete operator is also similar to the free() function because both methods are used to de-allocate memory during the execution of a C/C++ program but, when the delete operator is used with objects it invokes the destructor function of the class when the object is de-allocated, while free() doesn't invoke the destructor function.

Example C++ Program:

Output:

Explanation: We can see that, when an object dog was created using the new operator, the constructor is invoked. Also, we have created an object of Animal class (cat) using the malloc() function. When the delete operator is used with the dog object, it invokes the default destructor function. Whereas, when the free() function is called with the cat object, the destructor function is not called.

Conclusion

  • A system's memory is one of the most important resources available to us since it can be used as both static memory and dynamic memory.

  • Allocation and de-allocation of memory blocks during run-time is known as Dynamic Memory Allocation in C++.

  • DMA is a very essential concept in the field of data structures as Linked Lists, Stacks, Queues, Trees, etc., requirements allocation and de-allocation of memory blocks at run-time.

  • The new operator is used to allocate a memory block, while the delete operator is used to de-allocate a memory block.

  • In C language, we use malloc(), calloc(), and free functions, while in C++ language we use new and delete operators to allocate and de-allocate memory blocks at run-time.

Read More: