Programming Pandit

c/c++/c#/Javav/Python


Latest Update

Monday, September 14, 2026

Dynamic Allocation and Operators in C++

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.

Image

Image

Image

Image

Image

Image


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 = 50

Working

          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:

5

Output

Array elements: 10 20 30 40 50

Memory Concept

int *arr
   |
   ↓
+----+----+----+----+----+
| 10 | 20 | 30 | 40 | 50 |
+----+----+----+----+----+
  0    1    2    3    4

Image

Image

Image

Image

Image


7. 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();

Image

Image

Image

Image

Image


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: 101

Here:

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 called

Thus:

new object
    ↓
Constructor called
    ↓
Object exists
    ↓
delete object
    ↓
Destructor called

11. 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 50

13. 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 released

17. 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:

OperatorPurpose
newDynamically allocates one object
deleteReleases 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.

Featurenew/deletemalloc/free
LanguageC++C
Allocationnewmalloc()
Deallocationdeletefree()
Constructor calledYes, for objectsNo
Destructor calledYes, for objectsNo
Type returnedProperly typed pointervoid* in C
Array allocationnew[]malloc()
C++ object managementPreferredGenerally not preferred

Never Mix Them

Incorrect:

int *p = new int;

free(p);        // Wrong

Correct:

int *p = new int;

delete p;

Similarly:

int *p = (int*)malloc(sizeof(int));

delete p;       // Wrong

Use:

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 missing

This can cause a memory leak.


Error 2: Wrong delete operator

int *arr = new int[10];

delete arr;       // Incorrect

Correct:

delete[] arr;

Error 3: Accessing after deletion

int *p = new int(10);

delete p;

cout << *p;       // Undefined behavior

Error 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);          // Incorrect

Use 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: 103

22. 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
          ↓
      Destructor

Most 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