In C++, dynamic memory allocation allows programs to allocate and release memory during runtime. The new operator allocates memory from the free store (heap) and returns its address, while the delete operator releases the allocated memory when it is no longer needed.
- Provides greater flexibility than fixed-size stack allocation.
- Prevents memory wastage by releasing unused memory with delete.
Example: The following program dynamically allocates memory for an integer and initializes it.
#include <iostream>
#include <memory>
using namespace std;
int main() {
// Declared a pointer to store
// the address of the allocated memory
int *nptr;
// Allocate and initialize memory
nptr = new int(6);
// Print the value
cout << *nptr << endl;
// Print the address of memory
// block
cout << nptr;
return 0;
}
Output
6 0xb52dc20
Explanation
- new int(6) allocates memory for an integer and initializes it with 6.
- The returned address is stored in ptr.
- The allocated memory is released using delete.
Dynamic Memory Allocation Using new
The new operator allocates memory for a single object and returns a pointer to the allocated memory.
Syntax
pointer = new data_type;
or with initialization
pointer = new data_type(value);
Where:
- pointer stores the address of the allocated memory.
- data_type specifies the type of object to allocate.
- value is an optional initial value assigned during allocation.
Allocating Arrays Using new
The new operator can also allocate memory for arrays whose size is determined during runtime.
Syntax
pointer = new data_type[size];
Arrays can also be initialized during allocation.
Example: The following program dynamically allocates an integer array.
#include <iostream>
#include <memory>
using namespace std;
int main() {
// Declared a pointer to store
// the address of the allocated memory
int *nptr;
// Allocate and initialize array of
// integer with 5 elements
nptr = new int[5]{1, 2, 3, 4, 5};
// Print array
for (int i = 0; i < 5; i++)
cout << nptr[i] << " ";
return 0;
}
Output
1 2 3 4 5
Explanation
- new int[5] allocates memory for five integers.
- The array is initialized during allocation.
- delete[] is used because the memory was allocated as an array.
Note: Always use delete[] to deallocate memory allocated with new[].
Handling Allocation Failure
If sufficient memory is unavailable, memory allocation fails.
By default, new throws an exception of type std::bad_alloc. To avoid exceptions, use the nothrow version of new, which returns nullptr on failure.
#include <iostream>
#include <new>
using namespace std;
int main() {
int* ptr = new (nothrow) int;
if (ptr == nullptr)
cout << "Memory allocation failed";
delete ptr;
}
Releasing Memory Using delete
Memory allocated using new should be released when it is no longer needed.
Syntax
For a single object
delete ptr;
For an array
delete[] arr;
Example: The following program demonstrates deleting both a single object and an array.
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
int *ptr = NULL;
// Request memory for integer variable
// using new operator
ptr = new int(10);
if (!ptr) {
cout << "allocation of memory failed";
exit(0);
}
cout << "Value of *p: " << *ptr << endl;
// Free the value once it is used
delete ptr;
// Allocate an array
ptr = new int[3];
ptr[2] = 11;
ptr[1] = 22;
ptr[0] = 33;
cout << "Array: ";
for (int i = 0; i < 3; i++)
cout << ptr[i] << " ";
// Deallocate when done
delete[] ptr;
return 0;
}
Output
Value of *p: 10 Array: 33 22 11
Applications of Dynamic Memory
Dynamic memory allocation is commonly used when memory requirements cannot be determined at compile time.
- Allocating memory whose size is known only during program execution.
- Implementing dynamic data structures such as linked lists, trees, graphs, and dynamic arrays.
- Creating objects whose lifetime must extend beyond the scope of the function in which they are created.
Common Errors with Dynamic Memory Management
Improper use of new and delete can lead to memory-related errors.
Memory Leak
In Memory Leak allocated memory is never released.
- Memory remains allocated until the program terminates.
- Occurs when delete is forgotten or the pointer is lost.
Example
int* ptr = new int(10);
// delete ptr; // Missing
Solution: Release allocated memory using delete or use smart pointers whenever possible.
Dangling Pointer
A Dangling pointers refers to memory that has already been deallocated.
- Accessing it results in undefined behavior.
- May lead to crashes or garbage values.
Example
delete ptr;
cout << *ptr; // Undefined behaviour
Solution: Assign nullptr after deleting.
delete ptr;
ptr = nullptr;
Double Deletion
Double deletion occurs when delete is called more than once on the same memory.
- Leads to undefined behavior.
- May crash the program.
delete ptr;
delete ptr;
Solution: Set the pointer to nullptr after deletion.
delete ptr;
ptr = nullptr;
Mixing new/delete with malloc/free
- Do not mix C and C++ memory management.
- Use new/delete together and malloc/free together.
Use:
new -> delete
new[] -> delete[]
malloc() -> free()
Avoid:
new -> free()
malloc() -> delete
Placement new
Placement new constructs an object in an already allocated memory block instead of allocating new memory.
- Normal new allocates memory and constructs the object.
- Placement new only constructs the object in existing memory.
It is mainly used in:
- Memory pools
- Custom allocators
- Low-level system programming
- Embedded systems
Note: When an object is created using placement new, its memory is not automatically deallocated. The object's destructor must be called explicitly, and the underlying memory should be managed separately.