Dynamic Memory Management Using new and delete in C++

C’s dynamic memory allocation functions from <cstdlib> (or the legacy <stdlib.h> for C code) manage heap memory. Below is a practical usage example:

#include <cstdlib>

int main() {
    // Allocate single integer storage
    int* single_slot = static_cast<int*>(malloc(sizeof(int)));
    // Allocate contiguous array of 10 integers
    int* int_buffer = static_cast<int*>(malloc(sizeof(int) * 10));

    free(single_slot);
    free(int_buffer);

    // Allocate and zero-initialize 4 integers
    int* zeroed_array = static_cast<int*>(calloc(4, sizeof(int)));
    // Resize existing allocation to hold 100 integers
    int* resized_buffer = static_cast<int*>(realloc(zeroed_array, sizeof(int) * 100));

    // No need to free zeroed_array: realloc cleans it up on successful reallocation
    free(resized_buffer);
    return 0;
}

Note: realloc has nuanced behavior not covered here; consult additional resources for full implemantation details.

C++ new and Delete Operators

C++ introduces new and delete as dedicated dynamic memory management operators, which work alongside C’s standard functions while adding key improvements. For built-in data types such as int, double, or char, the core behavior aligns with malloc and free, with critical distinctions.

Usage for Built-in Types

#include <iostream>
using namespace std;

int main() {
    // Single-element allocation
    int* malloc_single = static_cast<int*>(malloc(sizeof(int)));
    int* new_single = new int;

    // Contiguous array allocation
    int* malloc_array = static_cast<int*>(malloc(sizeof(int) * 5));
    int* new_array = new int[5];

    free(malloc_single);
    delete new_single;
    free(malloc_array);
    delete[] new_array;
}

Critical note: Use new/delete for single-element allocations, and new[]/delete[] for contiguous array allocations to avoid undefined behavior.

A key advantage of new over malloc is built-in initialization support, which extends beyond the zero-initialization offered by calloc to flexible explicit values:

#include <iostream>
#include <cassert>
using namespace std;

int main() {
    // Allocate single integer initialized to 10
    int* initialized_single = new int(10);
    // Allocate array of 5 integers with explicit initial values
    int* initialized_array = new int[5] {1, 2, 3, 4, 5};
    // Allocate and zero-initialize 5 integers, matching calloc behavior
    int* calloc_match = static_cast<int*>(calloc(5, sizeof(int)));
    assert(calloc_match != nullptr);

    cout << *initialized_single << endl;

    cout << "initialized_array contents: ";
    for (int i = 0; i < 5; ++i) {
        cout << initialized_array[i] << " ";
    }
    cout << endl;

    cout << "First element of calloc-matching allocation: " << *calloc_match << endl;

    delete initialized_single;
    delete[] initialized_array;
    free(calloc_match);
    return 0;
}

Tags: C++ dynamic memory management new operator delete operator malloc comparison

Posted on Thu, 14 May 2026 10:32:23 +0000 by AnsonM