Dynamic memory allocation in C++ language is a powerful feature that allows programmers to allocate memory at runtime. This is especially useful when the size of the data structure is not known at compile time. The C++ language provides operators ‘new’ and ‘delete’ for dynamic memory management. This article explains everything about the Dynamic Memory Allocation in C++ language.
C++ Program Memory Management
When we execute our program in a computer system. It requires some space to store its instructions,local variables, global variables, and various other functions in C++. It is also known as memory in computers where statements will be stored.
There are two types of memory in our computer system: Static Memory and Dynamic Memory.
Static Memory: This is constant memory allocated by the operating system during a C++ program’s compile time. The operating system internally uses a stack data structure to manage the static memory allocation.
Dynamic Memory: Dynamic memory can be allocated or de-allocated by the operating system during a C++ program’s runtime. This is more efficient than static memory because we can deallocate and reuse our memory during the program’s runtime.
We can divide the memory into four parts which are used by the C++ program:
Stack Memory
Static Data Memory (for Global and Static Variable)
Instruction/Statements (Static Memory)
Heap (Dynamic Memory)
The Stack Memory
The stack memory stores local variables and function call information. It is based on the LIFO (Last in, First Out) structure, which means that the last piece of data added to the stack is the first one to be removed.
This memory allocated a constant space during the 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.
The size of stack memory is limited in the computer system. If too much memory is allocated on the stack, it can lead to a stack overflow, which can cause the program to crash. This is in contrast to heap memory which is larger and can grow dynamically, although it is slower to allocate and deallocate.
The Heap Memory
Heap memory, also known simply as the heap, is a region of a computer’s memory used for dynamic memory allocation. It allows memory blocks of arbitrary sizes to be allocated and deallocated at any time.
This memory is also known as the dynamic memory in our computer system. It is a large block of memory that is expandable and shrinkable during program execution.
The heap memory, which is typically limited in size and can lead to stack overflow errors if overused, can grow as needed(within the limits of the system’s physical and virtual memory). This allows for the creation of large data structures and arrays whose size might not be known at compile time.
The heap memory can become fragmented as blocks of memory are allocated and freed in a non-contiguous manner. This fragmentation can lead to inefficient memory usage and potentially slow down allocation and deallocation operations.
Get curriculum highlights, career paths, industry insights and accelerate your technology journey.
Download brochure
Types of Memory Allocation
We can classify memory into types: static memory allocation and dynamic memory allocation. Understanding these types helps in efficient memory management and ensures the optimal performance of C++ programs.
Static Memory Allocation: Static memory allocation is performed at compile time; this size and type of memory are determined before the program runs, and the memory is allocated on the stack. This type of allocation is used for variables whose size is known and fixed at compile time.
Dynamic Memory Allocation: Dynamic memory allocation is performed at runtime using operators like ‘new’ and ‘delete’. The memory is allocated on the heap, and the size can be adjusted as needed during program execution.
Why Dynamic Memory Allocation?
Dynamic memory allocation in C++ is a powerful feature that allows for flexible and efficient memory management at runtime. Let’s examine some reasons why dynamic memory allocation is commonly used in the C++ language.
Flexibility and Efficiency: The static memory allocation, where the size of data structures must be known at compile-time, dynamic memory allocation allows the allocation of memory for data structures whose sizes can be determined during runtime. This is particularly useful for applications where the amount of data cannot be predicted in advance.
Efficient Memory Usage: Dynamic memory allocation allows for the creation of data structures that use only as much memory as needed, which can lead to more efficient memory use. This is especially true in cases where data structures need to grow or shrink during the program’s execution.
Real-TimeSystems: Real-time systems need to allocate memory on the fly without causing interruptions. Dynamic memory allocation allows for the management of memory in a way that can meet real-time constraints.
How is it Different from Memory Allocated to Normal Variables?
Operating systems use static memory for allocation for normal data types in C++. For example, int r, double arr[30], char name [30], etc. int r, double arr[10]; char name[20]; etc. This memory is allocated automatically at compile time and de-allocated when the function block or program finishes by the operating system. The operating system uses the dynamic memory allocation for dynamically allocated variables in the program. For example, int *ptr = new int. This memory must be deallocated by the programmer when it is no longer required. Because memory leaks occur when the programmer forgets to deallocate the memory.
Creating the Dynamic Space in Memory: Create the dynamic memory space in the heap memory. Using the new operator in C++ language.
Storing its Address in a Pointer: After creating the dynamic space. We have to store the address of the allocated space in a pointer variable. This variable accesses and modifies the contents of the memory block.
Deleting the Allocated Space: When the developer does not require the memory block. We can delete the allocated space using the delete operator to free up the heap memory in the computer system.
The ‘new’ operator in C++
Dynamic memory allocation is a crucial concept in C++. It allows the creation of objects and arrays whose size is not known at compile time but determined at runtime. In this situation, we can use the ‘new’ operator in the C++ language, which allocates memory at runtime.
Syntax of ‘new’ operator
<strong>data_type * ptr = new data_type ;</strong>
ptr: This variable stores the address of the type.
data_type: It can be any predefined types like int, char, etc or other user-denied data types like classes, and can be used as the data_type with the new operator in C++
The following program demonstrates the ‘new’ operator in C++:
Program
# include <iostream><strong> </strong>
using namespace std ;
int main(){
int *ptr = new int ;
*ptr = 30 ;
cout << " Value at Memory pointed by ptr ="<< *ptr ;
}
Output
Value at Memory pointed by ptr =30
Initializing Dynamic Memory
Syntax
data_type* ptr_var = new data-type(value);
Example C++ Program
#include <iostream>
using namespace std;
int main()
{
// dynamically allocating an integer memory block
// with 12 as its initial value
int* ptr = new int(50);
cout << "Value at memory pointed by ptr= " << *ptr;
return 0;
}
Output
Value at memory pointed by ptr= 50
The ‘delete’ Operator in C++
In C++ language, the ‘delete’ operator is used to deallocate memory that was previously allocated using the ‘new’ operator. When you allocate memory dynamically, it resides on the heap or free store, and it’s your responsibility to free this memory when it’s no longer needed to prevent memory leaks.
Syntax of ‘delete’ operator
delete ptr_variable ;
Syntax to delete an array of memory
delete[] ptr_variable ;
The following program demonstrates the delete program
Program
#include <iostream>
using namespace std;
int main()
{
int* numbers = new int;
*numbers = 505300;
cout<<"Visible stars in the sky: "<<*numbers;
// stars memory deallocated using the delete operator
delete numbers;
cout<<"nGarbage value: "<<*numbers;
numbers = NULL;
return 0;
}
Output
Visible stars in the sky: 505300
Garbage value: 0
Dynamic Memory Allocation in C++ for Arrays
The new operator can also allocate a block of memory (an array) of any data type.
Syntax
data_type* ptr = new data_type[size_of_the_array] ;
Example
char *name = new char[30]
Standard Array Declaration vs Using the ‘new’ operator
In C++ language, We can declare in two primary ways, using standard array declarations and the ‘new operator. Each method has its own use cases, advantages and limitations. Here’s a detailed comparison of the two approaches:
Feature
Standard Array Declaration
Using ‘new’ Operator
Size
The fixed, known at compile time
Dynamic, determined at runtime
Memory Allocation
Stack
Heap
Deallocation
Automatic
Manual(using delete[])
Flexibility
Limited to compile-time size
Flexible, runtime size
Performance
Faster Allocation
Potentially slower due to heap management
The following program with a new operator in C++:
Program
#include <iostream>
using namespace std;
int main()
{
int* arr = new int[5];
cout << "Enter 5 values in the array: ";
for(int i = 0; i < 5; i++){
cin >> arr[i];
}
cout << "nArray elements: ";
for(int i = 0; i < 5; i++)
{
cout << arr[i] << " ";
}
delete [] arr;
cout << "nGarbage array values after deallocation of array memory: ";
for(int i = 0; i < 5; i++){
cout << arr[i] << " ";
}
return 0;
}
Output
Enter 5 values in the array: 5 20 30 39 3
Array elements: 5 20 30 39 3
Garbage array values after deallocation of array memory: 0 0 13066256 0 3
Dynamic Memory Allocation in C++ for Objects
In the C++ language, we can also allocate dynamic memory for objects. When we create an object of a class, a constructor function is invoked. A constructor is a member function of a class that is used to initialize the object.
The following program demonstrates the dynamic memory allocation in C++:
Program
#include <iostream>
using namespace std;
class Cats
{
public:
Cats() {
cout << "Cat class constructor invoked!" <<endl;
}
~Cats() {
cout << "Cat class destructor invoked!" <<endl;
}
};
int main() {
Cats* cat = new Cats;
delete cat;
return 0;
}
Output
Cat class constructor invoked!
Cat class destructor invoked!
Comparison with “malloc()”, “calloc()”, and “free()” functions of C
Let’s understand the malloc() , calloc() and free() library function definition before moving forward:
C Functions
Definitions
Syntax
malloc()
This function is used for dynamic memory allocation. This function returns arguments’ size (in bytes) and returns a void pointer to the allocated pointer’s first byte
(cast-data-type*)malloc(size-in-bytes)
calloc()
The ‘calloc’ function allocates memory for an array of elements, initializes all bytes in the allocated storage to zero, and then returns a pointer to the memory.
void* calloc(size_t num, size_t size);
free()
This function is used to clear the allocated space (deallocate) from the heap memory.
free(ptr)
“new” vs “malloc()” and “calloc()”
The new operator has similar working as malloc() and calloc() functions. These functions are used to allocate memory during the program execution in C++ and C programs. But when we use a new operator, it invokes the constructor function of the class. But the malloc() and calloc() functions do not invoke the constructor function.
Example C++ Program:
#include <iostream>
using namespace std;
class Animal {
public:
Animal() {
cout << "Animal class constructor invoked!" <<endl;
}
~Animal() {
cout << "Animal class destructor invoked!" <<endl;
}
};
int main() {
Animal* dog = new(nothrow) Animal;
Animal* dogs = new(nothrow) Animal[5];
Animal* cat = (Animal*)malloc(sizeof(Animal));
Animal* cats = (Animal*)calloc(5, sizeof(Animal));
return 0;
}
Output
Animal class constructor invoked!
Animal class constructor invoked!
Animal class constructor invoked!
Animal class constructor invoked!
Animal class constructor invoked!
Animal class constructor invoked!
“delete” vs “free()”
In C++ language, ‘delete’ and free()’ are both used to deallocate dynamically allocated memory. But they have some significant differences. The ‘delete’ is used to deallocate memory that was allocated with ‘new’, and it also calls the destructor of the object, ensuring proper cleanup of resources.
The following program demonstrates the “delete vs free()”:
Program
#include <iostream>
using namespace std;
class Animal {
public:
Animal() {
cout << "Animal class constructor invoked!" <<endl;
}
~Animal() {
cout << "Animal class destructor invoked!" <<endl;
}
};
int main() {
Animal* dog = new(nothrow) Animal;
Animal* cat = (Animal*)malloc(sizeof(Animal));
delete dog;
free(cat);
return 0;
}
Output
Animal class constructor invoked!
Animal class destructor invoked!
Conclusion
In this article, we learned about the dynamic memory allocation in C++ language. It is a powerful feature that allows developers to allocate memory at runtime. This provides flexibility in managing memory for various data structures and objects. The ‘new’ and ‘delete’ operators offer a robust mechanism for allocating and deallocating memory, ensuring that constructors and destructors are called, which is essential for resource management and avoiding memory leaks. By understanding these functions, C++ developers can leverage these tools and write more efficient, reliable and maintainable source code.
FAQs
1. What is dynamic memory allocation in C++?
It is the process of allocating memory at runtime using operators like ‘new’ and ‘new[]’. This allows the program to request memory from the heap as needed rather than relying solely on stack memory or static memory allocation.
2. Where is the dynamic allocation of variables done?
Dynamically allocated variables live in a piece of memory known as the heap. The running program requests them using the keyword ‘new’.
3. What is the difference between stack and heap memory, and when should you use each?
Stack Memory: This memory is used for local variables and function calls. This is limited in size and scope. It is fast but not suitable for large or dynamically sized data.
Heap Memory: Managed manually or with smart pointers, used for dynamic memory allocation. It allows for more flexible and larger memory allocation but requires careful management to avoid leaks and fragmentation.
Hero Vired is a leading LearnTech company dedicated to offering cutting-edge programs in collaboration with top-tier global institutions. As part of the esteemed Hero Group, we are committed to revolutionizing the skill development landscape in India. Our programs, delivered by industry experts, are designed to empower professionals and students with the skills they need to thrive in today’s competitive job market.