EZ

Eduzan

Learning Hub

Eduzan
Eduzan / C++

Dynamic Memory

Computer Science / C++ tutorial chapter - Published 2025-12-13 - C++

Dynamic memory allocation in C/C++ allows programmers to manually manage memory usage, specifically allocating memory on the heap. Unlike stack-allocated memory for local and static variables, dynamic allocation provides the flexibility to allocate and deallocate memory at runtime, which is especially useful for structures like linked lists and trees.

Applications of Dynamic Memory Allocation

One key application of dynamic memory allocation is the ability to handle variable-sized memory requirements, which isn’t feasible with static allocations (except for variable-length arrays). This flexibility is crucial in numerous scenarios, such as creating dynamic data structures.

Differences from Static Memory Allocation

For static variables, such as int a or char str[10], memory management is automatic—allocated and deallocated by the compiler. Conversely, for dynamically allocated memory (e.g., int *p = new int[10]), the programmer is responsible for deallocation. Failure to do so can lead to memory leaks, where the memory remains allocated until the program terminates.

Memory Management in C++

C uses functions like malloc() and calloc() for dynamic memory allocation, along with free() for deallocation. C++, however, offers a more streamlined approach using the new and delete operators.

Using the new Operator

The new operator requests memory allocation from the heap. If successful, it returns a pointer to the allocated memory.

Syntax :

pointer-variable = new data-type;

Example:

#include <iostream>
using namespace std;

int main() {
    // Pointer to store the address of allocated memory
    int* ptr = new int; // Allocates memory for an integer
    *ptr = 10;          // Assigns a value to the allocated memory

    // Printing the address and value
    cout << "Address: " << ptr << endl;
    cout << "Value: " << *ptr << endl;

    delete ptr; // Deallocating the memory
    return 0;
}

Initializing Dynamically Allocated Memory

You can also initialize memory directly upon allocation:

Example:

#include <iostream>
using namespace std;

struct CustomType {
    int value;
    CustomType(int v) : value(v) {}
};

int main() {
    int* p = new int(42); // Initializes an integer with 42
    CustomType* obj = new CustomType(100); // Initializes CustomType

    cout << *p << " " << obj->value << endl;

    delete p;     // Deallocate integer
    delete obj;   // Deallocate CustomType
    return 0;
}

Output:

a + b = 30
a - b = 20
a * b = 125
a / b = 5
a % b = 0
+a = 25
-a = -25
a++ = 25
a-- = 26

Allocating Arrays : You can allocate memory for an array using the new operator:

Example:

#include <iostream>
using namespace std;

int main() {
    int n = 5;
    int* array = new int[n]; // Allocates memory for an array of 5 integers

    for (int i = 0; i < n; ++i) {
        array[i] = i * 2; // Initializing array elements
    }

    // Displaying the values
    for (int i = 0; i < n; ++i) {
        cout << array[i] << " "; // Outputs: 0 2 4 6 8
    }

    delete[] array; // Deallocate the array
    return 0;
}

Output:

a < b  : 0
a > b  : 1
a <= b: 0
a >= b: 1
a == b: 0
a != b : 1

Handling Memory Allocation Failures : When memory allocation fails, the new operator throws a std::bad_alloc exception unless nothrow is used:

Example:

#include <iostream>
using namespace std;

int main() {
    int* p = new(nothrow) int; // Attempt to allocate memory
    if (!p) {
        cout << "Memory allocation failed\n";
    } else {
        *p = 42;
        cout << "Value: " << *p << endl;
        delete p; // Deallocate memory
    }
    return 0;
}

Output:

a && b : 1
a || b : 1
!a: 0

The delete Operator: To free memory allocated with new, use the delete operator:

Syntax:

delete pointer-variable;        // For single objects
delete[] pointer-variable;      // For arrays

Example:

#include <iostream>
using namespace std;

int main() {
    int* singleInt = new int(5);
    float* floatValue = new float(10.5);

    cout << "Integer: " << *singleInt << endl;
    cout << "Float: " << *floatValue << endl;

    delete singleInt; // Freeing single integer memory
    delete floatValue; // Freeing float memory

    int n = 3;
    int* intArray = new int[n]; // Allocating an array
    for (int i = 0; i < n; ++i) {
        intArray[i] = i + 1;
    }

    cout << "Array values: ";
    for (int i = 0; i < n; ++i) {
        cout << intArray[i] << " "; // Outputs: 1 2 3
    }

    delete[] intArray; // Freeing the entire array
    return 0;
}

In C++, memory can be dynamically allocated using the new and delete operators, while C and C++ also provide the malloc() and free() functions for similar purposes. Though they seem to serve the same function, there are key differences between them.

#include <iostream>
using namespace std;

// Class A
class A {
    int a;
public:
    int* ptr;

    // Constructor of class A
    A() {
        cout << "Constructor was Called!" << endl;
    }
};

// Driver Code
int main() {
    // Creating an object of class A using new
    A* a = new A;
    cout << "Object of class A was created using new operator!" << endl;

    // Creating an object of class A using malloc
    A* b = (A*)malloc(sizeof(A));
    cout << "Object of class A was created using malloc()!" << endl;

    // Cleanup
    delete a;
    free(b); // Note: This does not call the destructor
    return 0;
}

Output:

Constructor was Called!
Object of class A was created using new operator!
Object of class A was created using malloc()!
End of lesson.