Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Industrial programming >> C Language

Dynamic Memory Allocation in C: Mastering malloc, calloc, realloc, and free

Dynamic Memory Allocation in C

This guide walks you through dynamic memory allocation in C using the standard library functions malloc(), calloc(), realloc(), and free(), with clear examples and best‑practice tips.

Why Use Dynamic Allocation?

Static arrays have a fixed size declared at compile time, which can lead to wasted space or insufficient capacity during runtime. Dynamic allocation lets you request exactly the amount of memory you need while the program is running.

All four functions are defined in the <stdlib.h> header and provide a controlled way to manage heap memory.


malloc() – Allocate a Block of Bytes

The name malloc stands for "memory allocation." It reserves a contiguous block of memory of the specified size (in bytes) and returns a pointer of type void * that can be cast to any other pointer type.

Syntax

ptr = malloc(size_in_bytes); // cast to desired type if needed

Example

float *ptr = malloc(100 * sizeof(float)); // 400 bytes on most systems

Here, ptr points to the first byte of a 400‑byte block. If the request fails, malloc returns NULL. It is recommended to avoid unnecessary casts in C; the compiler can deduce the type when you assign the result to a typed pointer.


calloc() – Allocate and Zero‑Initialize

calloc stands for "contiguous allocation." Unlike malloc, it initializes every bit of the allocated block to zero, making it safe for numeric types and pointers.

Syntax

ptr = calloc(num_elements, size_of_each_element);

Example

float *ptr = calloc(25, sizeof(float)); // 25 zeroed float elements

The returned pointer is NULL if the allocation fails.


free() – Release Allocated Memory

Memory obtained with malloc or calloc persists until you explicitly release it. free() deallocates the block and returns the memory to the heap for future reuse.

Syntax

free(ptr);

Calling free on a NULL pointer is safe and does nothing.


Example 1: Using malloc() and free()

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n, i, *ptr, sum = 0;

    printf("Enter number of elements: ");
    scanf("%d", &n);

    ptr = malloc(n * sizeof(int));
    if (!ptr) {
        fprintf(stderr, "Error: memory not allocated.\n");
        return EXIT_FAILURE;
    }

    printf("Enter elements: ");
    for (i = 0; i < n; ++i) {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }

    printf("Sum = %d\n", sum);
    free(ptr);
    return EXIT_SUCCESS;
}

Output

Enter number of elements: 3
Enter elements: 100 20 36
Sum = 156

Example 2: Using calloc() and free()

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n, i, *ptr, sum = 0;

    printf("Enter number of elements: ");
    scanf("%d", &n);

    ptr = calloc(n, sizeof(int));
    if (!ptr) {
        fprintf(stderr, "Error: memory not allocated.\n");
        return EXIT_FAILURE;
    }

    printf("Enter elements: ");
    for (i = 0; i < n; ++i) {
        scanf("%d", ptr + i);
        sum += *(ptr + i);
    }

    printf("Sum = %d\n", sum);
    free(ptr);
    return EXIT_SUCCESS;
}

Output

Enter number of elements: 3
Enter elements: 100 20 36
Sum = 156

realloc() – Resize an Existing Allocation

If you discover that your current allocation is too small or larger than needed, realloc() adjusts the size while preserving the existing data (up to the new size).

Syntax

ptr = realloc(ptr, new_size_in_bytes);

It returns a pointer to the reallocated block or NULL on failure. To avoid memory leaks, store the result in a temporary pointer first.

Example 3: Using realloc()

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *ptr, i, n1, n2;

    printf("Enter initial size: ");
    scanf("%d", &n1);

    ptr = malloc(n1 * sizeof(int));
    if (!ptr) {
        fprintf(stderr, "Allocation failed.\n");
        return EXIT_FAILURE;
    }

    printf("Addresses before reallocation:\n");
    for (i = 0; i < n1; ++i)
        printf("%p\n", ptr + i);

    printf("\nEnter new size: ");
    scanf("%d", &n2);

    int *tmp = realloc(ptr, n2 * sizeof(int));
    if (!tmp) {
        fprintf(stderr, "Reallocation failed.\n");
        free(ptr);
        return EXIT_FAILURE;
    }
    ptr = tmp;

    printf("Addresses after reallocation:\n");
    for (i = 0; i < n2; ++i)
        printf("%p\n", ptr + i);

    free(ptr);
    return EXIT_SUCCESS;
}

Typical Output

Enter initial size: 2
Addresses before reallocation:
0x7ffc12345670
0x7ffc12345674

Enter new size: 4
Addresses after reallocation:
0x7ffc12345670
0x7ffc12345674
0x7ffc12345678
0x7ffc1234567c

By mastering these four functions and applying proper error handling, you can manage heap memory safely and efficiently in any C application.

C Language

  1. Understanding ROM, PROM, EPROM, and EEPROM: Design, Programming, and Identification
  2. Understanding Look‑Up Tables: From ROMs to Advanced ALUs
  3. Microprocessors: The Evolution of Stored‑Program Computing
  4. Master C++ Dynamic Array Allocation: A Practical Guide with Code Examples
  5. Dynamic Memory Allocation in C: Mastering malloc, calloc, realloc, and free
  6. Java Stack vs. Heap: A Practical Memory Allocation Guide
  7. Dynamic Memory Management in C: calloc, malloc, and free Explained
  8. Mastering C++ Dynamic Memory: Stack vs. Heap Explained
  9. Java 10 Enhancements: Allocate Heap on NV‑DIMM with -XX:AllocateHeapAt
  10. G.AL® C330 Dynamic: High-Strength Aluminum Alloy for Precision Applications