Dynamic Allocation and Operators in C++
Dynamic memory allocation is an important feature of C++ that allows a program to allocate and release memory during runtime. Unlike ordinary variables whose memory is generally determined when the program enters a scope, dynamically allocated memory is obtained from the free store (commonly called the heap) when required.
C++ provides the operators new and delete for dynamic memory management.
1. Need for Dynamic Memory Allocation
Consider an array:
int marks[50];The size is fixed at the time of declaration. If the program later requires 100 elements, the original array cannot be resized.
Dynamic allocation allows memory to be requested according to the requirement at runtime.
For example:
int n;
cout << "Enter number of elements: ";
cin >> n;
int *p = new int[n];Here, the number of integers is decided during program execution.
Advantages
Dynamic allocation is useful when:
The required memory size is not known beforehand.
Memory needs to be allocated only when required.
Large objects or arrays need controlled lifetime.
Dynamic data structures such as linked lists, trees, and graphs are implemented.
Objects need to be created and destroyed explicitly during program execution.
2. new Operator
The new operator dynamically allocates memory and returns the address of the allocated memory.
Syntax
For a single variable:
pointer = new data_type;Example:
int *p = new int;Memory for one int is allocated, and its address is stored in p.
We can assign a value using:
*p = 25;or initialize it directly:
int *p = new int(25);3. Dynamic Allocation of a Single Variable
#include <iostream>
using namespace std;
int main()
{
int *p = new int;
*p = 50;
cout << "Value = " << *p << endl;
delete p;
return 0;
}Output
Value = 50Working
Pointer p
|
| address
↓
+-----------+
Heap → | 50 |
+-----------+The statement:
int *p = new int;allocates memory dynamically.
The statement:
delete p;releases that memory.
4. delete Operator
The delete operator releases memory that was allocated using new.
Syntax
delete pointer;Example:
int *p = new int(100);
cout << *p;
delete p;After:
delete p;the dynamically allocated object no longer exists.
It is good practice to avoid subsequently using the pointer to access the released object. A pointer can be set to nullptr after deletion:
delete p;
p = nullptr;5. Dynamic Allocation of Arrays
C++ provides new[] for dynamically allocating an array.
Syntax
pointer = new data_type[size];Example:
int *arr = new int[5];This creates an array of five integers dynamically.
The elements can be accessed using:
arr[0]
arr[1]
arr[2]or pointer notation:
*(arr + 0)
*(arr + 1)
*(arr + 2)6. Example of Dynamic Array
#include <iostream>
using namespace std;
int main()
{
int n;
cout << "Enter number of elements: ";
cin >> n;
int *arr = new int[n];
for(int i = 0; i < n; i++)
{
arr[i] = (i + 1) * 10;
}
cout << "Array elements: ";
for(int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
delete[] arr;
arr = nullptr;
return 0;
}For input:
5Output
Array elements: 10 20 30 40 50Memory Concept
int *arr
|
↓
+----+----+----+----+----+
| 10 | 20 | 30 | 40 | 50 |
+----+----+----+----+----+
0 1 2 3 47. delete[] Operator
When an array is allocated using:
new[]it must be released using:
delete[]Example:
int *arr = new int[10];
delete[] arr;
arr = nullptr;Important Rule
new → delete
new[] → delete[]Do not use:
delete arr;for memory allocated as:
new int[10];The correct form is:
delete[] arr;8. Dynamic Allocation of Objects
The new operator can also dynamically create an object.
Suppose:
class Student
{
public:
int rollNo;
void display()
{
cout << "Roll No: " << rollNo << endl;
}
};An object can be dynamically created using:
Student *ptr = new Student;The member can be accessed using the arrow operator:
ptr->rollNo = 101;
ptr->display();9. Example: Dynamic Object
#include <iostream>
using namespace std;
class Student
{
public:
int rollNo;
void display()
{
cout << "Roll No: " << rollNo << endl;
}
};
int main()
{
Student *ptr = new Student;
ptr->rollNo = 101;
ptr->display();
delete ptr;
ptr = nullptr;
return 0;
}Output
Roll No: 101Here:
Student *ptr = new Student;creates a Student object dynamically.
The pointer ptr stores its address.
10. Dynamic Allocation with Constructor
When an object is created using new, its constructor is automatically called.
#include <iostream>
using namespace std;
class Student
{
public:
Student()
{
cout << "Constructor called" << endl;
}
~Student()
{
cout << "Destructor called" << endl;
}
};
int main()
{
Student *s = new Student;
delete s;
return 0;
}Output
Constructor called
Destructor calledThus:
new object
↓
Constructor called
↓
Object exists
↓
delete object
↓
Destructor called11. Dynamic Array of Objects
An array of objects can also be dynamically allocated.
Syntax
ClassName *ptr = new ClassName[size];Example:
Student *students = new Student[5];This creates five Student objects dynamically.
Each object can be accessed using:
students[0]
students[1]
students[2]or:
(students + 0)->display();12. Dynamic Allocation with Initialization
C++ allows dynamically allocated objects to be initialized.
For a fundamental type:
int *p = new int(100);For an object:
Student *s = new Student();For an array:
int *arr = new int[5]{10, 20, 30, 40, 50};Example:
#include <iostream>
using namespace std;
int main()
{
int *arr = new int[5]{10, 20, 30, 40, 50};
for(int i = 0; i < 5; i++)
cout << arr[i] << " ";
delete[] arr;
return 0;
}Output
10 20 30 40 5013. What Happens When Memory Allocation Fails?
Normally:
int *p = new int;successfully allocates memory.
If a normal new expression cannot allocate the requested memory, it throws a std::bad_alloc exception.
Example:
try
{
int *p = new int[1000000000000];
}
catch (const bad_alloc &e)
{
cout << "Memory allocation failed";
}For modern C++, this is generally preferable to assuming new simply returns NULL.
There is also a nothrow version:
int *p = new(nothrow) int[1000000];
if(p == nullptr)
{
cout << "Memory allocation failed";
}The nothrow form returns nullptr instead of throwing std::bad_alloc.
14. Dynamic Allocation and Memory Leak
A memory leak occurs when dynamically allocated memory is no longer accessible but has not been released.
Example:
int *p = new int(50);
p = nullptr;The allocated memory is still present, but its address has been lost.
Therefore, it cannot be released using delete.
p
|
↓
nullptr
Heap:
+-------+
| 50 | ← inaccessible memory
+-------+This is a memory leak.
Correct approach:
int *p = new int(50);
delete p;
p = nullptr;15. Dangling Pointer
A dangling pointer is a pointer that still contains the address of an object whose lifetime has ended.
Example:
int *p = new int(50);
delete p;Now p should not be dereferenced.
Better:
delete p;
p = nullptr;Then:
if(p != nullptr)
{
cout << *p;
}This prevents accidental access through the pointer.
16. new and delete with Classes
Dynamic allocation is particularly important in object-oriented programming because objects can have constructors and destructors.
class Employee
{
int id;
public:
Employee(int x)
{
id = x;
}
void display()
{
cout << "ID = " << id << endl;
}
};Dynamic object:
Employee *e = new Employee(101);
e->display();
delete e;The sequence is:
new Employee(101)
↓
Constructor executes
↓
Object created
↓
e->display()
↓
delete e
↓
Destructor executes
↓
Memory released17. Dynamic Allocation Operators and Ordinary Operators
The term operator in C++ refers to symbols that perform operations on operands. Dynamic memory management uses special operators:
| Operator | Purpose |
|---|---|
new | Dynamically allocates one object |
delete | Releases one dynamically allocated object |
new[] | Dynamically allocates an array |
delete[] | Releases a dynamically allocated array |
Example:
int *p = new int;
delete p;and:
int *arr = new int[10];
delete[] arr;18. new/delete vs malloc/free
C++ programs may encounter the C functions malloc() and free(), but they should not be confused with C++ new and delete.
| Feature | new/delete | malloc/free |
|---|---|---|
| Language | C++ | C |
| Allocation | new | malloc() |
| Deallocation | delete | free() |
| Constructor called | Yes, for objects | No |
| Destructor called | Yes, for objects | No |
| Type returned | Properly typed pointer | void* in C |
| Array allocation | new[] | malloc() |
| C++ object management | Preferred | Generally not preferred |
Never Mix Them
Incorrect:
int *p = new int;
free(p); // WrongCorrect:
int *p = new int;
delete p;Similarly:
int *p = (int*)malloc(sizeof(int));
delete p; // WrongUse:
free(p);when memory was allocated with malloc().
19. Modern C++ Recommendation
Although new and delete are fundamental concepts and are important for understanding C++ memory management, modern C++ generally recommends RAII and smart pointers for managing dynamically allocated resources.
For example:
#include <memory>
unique_ptr<int> p = make_unique<int>(100);The memory is automatically released when p goes out of scope.
Similarly:
auto student = make_unique<Student>();is preferred in many modern applications over manually writing:
Student *student = new Student;
delete student;However, understanding new, delete, new[], and delete[] remains essential for understanding pointers, object lifetime, constructors/destructors, and legacy C++ code.
20. Common Errors
Error 1: Forgetting delete
int *p = new int(10);
// delete missingThis can cause a memory leak.
Error 2: Wrong delete operator
int *arr = new int[10];
delete arr; // IncorrectCorrect:
delete[] arr;Error 3: Accessing after deletion
int *p = new int(10);
delete p;
cout << *p; // Undefined behaviorError 4: Losing the allocated address
int *p = new int(10);
p = nullptr;The allocated memory is leaked.
Error 5: Mixing allocation and deallocation mechanisms
int *p = new int;
free(p); // IncorrectUse matching mechanisms.
21. Complete Example
#include <iostream>
using namespace std;
class Student
{
public:
int rollNo;
Student()
{
rollNo = 0;
}
void display()
{
cout << "Roll No: " << rollNo << endl;
}
};
int main()
{
// Dynamic object
Student *s = new Student;
s->rollNo = 101;
s->display();
// Dynamic array of objects
Student *students = new Student[3];
students[0].rollNo = 101;
students[1].rollNo = 102;
students[2].rollNo = 103;
cout << "\nStudent records:\n";
for(int i = 0; i < 3; i++)
{
students[i].display();
}
// Release memory
delete s;
s = nullptr;
delete[] students;
students = nullptr;
return 0;
}Output
Roll No: 101
Student records:
Roll No: 101
Roll No: 102
Roll No: 10322. Summary
Dynamic allocation allows C++ programs to obtain memory at runtime according to program requirements. The new operator allocates memory and returns an appropriate pointer, while delete releases a single dynamically allocated object. For arrays, C++ provides new[] and delete[].
The concept becomes especially important in object-oriented programming because dynamically created objects are initialized through constructors and destroyed through destructors. Proper memory management is essential to avoid memory leaks, dangling pointers, and undefined behavior.
Quick Revision
Dynamic Memory
|
+---------+---------+
| |
Single Array
| |
new new[]
| |
delete delete[]
|
Dynamic Object
|
Constructor
↓
Object
↓
delete
↓
DestructorMost important rule to remember:
new → delete
new[] → delete[]And for modern C++:
Prefer RAII / smart pointers
when manual ownership is not specifically required.
No comments:
Post a Comment