Fundamentals 9 min read

Master Dynamic Memory Allocation in C: malloc, calloc, realloc & free

This guide explains how to allocate, initialize, resize, and release heap memory in C using malloc, calloc, realloc, memset, and free, with clear examples, common pitfalls like memory leaks, and best‑practice recommendations for safe memory management.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Master Dynamic Memory Allocation in C: malloc, calloc, realloc & free

Heap Memory Allocation (malloc)

The malloc function reserves a contiguous block of memory of the requested size and returns its starting address as a void*. On failure it returns NULL. The allocated memory is uninitialized and must be released manually with free.

#include <stdlib.h>
void *malloc(size_t size);

Allocates a specified number of bytes.

Memory is contiguous.

Requires explicit free later.

Does not zero‑initialize the memory.

Example: Allocate space for a string

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
    char *str = "example";
    char *pb = NULL;
    pb = (char *)malloc(sizeof(char) * (strlen(str) + 1));
    if (pb == NULL) return 1;
    strcpy(pb, str);
    printf("pb = %s
", pb);
    free(pb);
    return 0;
}

Releasing Heap Memory (free)

The free function releases a previously allocated block, taking the pointer returned by malloc, calloc, or realloc as its argument.

#include <stdlib.h>
void free(void *ptr);

Initializing Memory (memset)

memset

sets the first n bytes of a memory area pointed to by s to the byte value c (commonly 0). It is useful for initializing or clearing buffers.

#include <string.h>
void *memset(void *s, int c, size_t n);

Example: Fill a character array with 'A'

#include <stdio.h>
#include <string.h>
int main(void)
{
    char str[10];
    memset(str, 'A', 5);   // first 5 bytes become 'A'
    str[5] = '\0';        // null‑terminate for printing
    printf("%s
", str); // prints "AAAAA"
    return 0;
}

Zero‑Initialized Allocation (calloc)

calloc

allocates memory for an array of nmemb elements, each of size bytes, and automatically initializes all bytes to zero. It returns a void* pointer or NULL on failure.

#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);

Example: Read a list of integers using calloc

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

void Input(int *p, int n)
{
    for (int i = 0; i < n; ++i) scanf("%d", p + i);
}

void Output(const int *p, int n)
{
    for (int i = 0; i < n; ++i) printf("%d ", p[i]);
    printf("
");
}

int main(void)
{
    int n;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    int *p = (int *)calloc(n, sizeof(int));
    if (p == NULL) return 1;
    Input(p, n);
    Output(p, n);
    free(p);
    return 0;
}

Resizing Allocated Memory (realloc)

realloc

changes the size of a previously allocated memory block. If the new size can be accommodated in place, the same pointer is returned; otherwise a new block is allocated, the old contents are copied, and the old block is freed. On failure it returns NULL and the original block remains unchanged.

#include <stdlib.h>
void *realloc(void *ptr, size_t size);

Example: Expand an integer array from 5 to 10 elements

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

int main(void)
{
    int *arr = (int *)malloc(5 * sizeof(int));
    if (arr == NULL) {
        printf("Allocation failed
");
        return 1;
    }
    // Expand to hold 10 integers
    int *tmp = (int *)realloc(arr, 10 * sizeof(int));
    if (tmp == NULL) {
        printf("Reallocation failed
");
        free(arr);
        return 1;
    }
    arr = tmp;
    for (int i = 0; i < 10; ++i) arr[i] = i;
    for (int i = 0; i < 10; ++i) printf("%d ", arr[i]);
    printf("
");
    free(arr);
    return 0;
}

Memory Leaks

A memory leak occurs when dynamically allocated memory is not released before the program loses all references to it, causing the process to consume more memory over time and potentially crash.

Forgotten free calls for allocated pointers.

Returning pointers to local (stack) variables.

Complex data structures where inner allocations are not freed.

Detection tools such as static analyzers or runtime profilers (e.g., Valgrind) can locate leaks. Writing clear allocation‑deallocation logic and, in C++, using smart pointers are common mitigation strategies.

Summary

Use malloc or calloc to obtain heap memory, optionally initialize it with memset, resize with realloc when needed, and always release it with free to avoid leaks.

C++mallocFreememsetrealloccalloc
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.