📘 Lesson  ·  Lesson 57

Dynamic Memory (malloc/free)

Why do we need dynamic memory?

When you write int a[100];, you must decide the size — 100 — while writing the code. But what if you do not know how many items you will have until the program runs? Maybe the user decides. Fixing the size in advance either wastes memory or runs out of room.

Dynamic memory allocation solves this. It lets your program request exactly as much memory as it needs, while it is running, from a large pool called the heap. You get back a pointer to that memory, use it, and return it when done.

The four functions

These live in <stdlib.h>:

FunctionWhat it does
malloc(size)Allocates a block of size bytes (contents are garbage)
calloc(n, size)Allocates n elements and sets all bytes to 0
realloc(p, size)Resizes an already-allocated block
free(p)Releases the memory back to the system

malloc: allocate a block

malloc takes the total number of bytes you want. We usually multiply by sizeof to be safe across systems.

C Language
#include <stdio.h>
#include <stdlib.h>
int main() {
    int *arr = malloc(3 * sizeof(int));   // space for 3 ints
    if (arr == NULL) return 1;            // always check!

    arr[0] = 10; arr[1] = 20; arr[2] = 30;
    printf("%d %d %d\n", arr[0], arr[1], arr[2]);

    free(arr);                            // give it back
    return 0;
}
Output:
10 20 30
⚠️ Always check for NULL

If the system cannot give the memory, malloc returns NULL. Using a NULL pointer crashes the program, so check it before use.

calloc: allocate and zero

calloc is like malloc but it also clears the memory to 0, and it takes the count and element size separately.

C Language
#include <stdio.h>
#include <stdlib.h>
int main() {
    int *arr = calloc(3, sizeof(int));   // 3 ints, all zero
    if (arr == NULL) return 1;

    printf("%d %d %d\n", arr[0], arr[1], arr[2]);  // 0 0 0
    free(arr);
    return 0;
}
Output:
0 0 0

With malloc those values would have been garbage. Use calloc when you want a clean, zeroed start.

realloc: resize a block

Suppose you allocated space for 3 ints but now need 5. realloc grows the block, keeping the old values.

C Language
#include <stdio.h>
#include <stdlib.h>
int main() {
    int *arr = malloc(3 * sizeof(int));
    arr[0] = 1; arr[1] = 2; arr[2] = 3;

    arr = realloc(arr, 5 * sizeof(int));  // grow to 5
    arr[3] = 4; arr[4] = 5;

    for (int i = 0; i < 5; i++) printf("%d ", arr[i]);
    free(arr);
    return 0;
}
Output:
1 2 3 4 5
💡 Safe realloc

realloc may move the block, so always assign its result back to a pointer (ideally a temporary one you check) rather than assuming the old pointer is still valid.

free and memory leaks

Every block you allocate must be released with free. If you forget, that memory stays reserved until the program ends — a memory leak. In a program that runs for hours, leaks pile up and can crash it.

C Language
int *p = malloc(sizeof(int));
*p = 42;
free(p);      // release the memory
p = NULL;     // avoid a dangling pointer
⚠️ Two dangers

Memory leak = you never free. Dangling pointer = you use a pointer after freeing it. Setting p = NULL after free protects against the second.

Common mistakes

  • Not checking whether malloc/calloc returned NULL before using the memory.
  • Forgetting to free, causing a memory leak.
  • Using or freeing a pointer twice, or using it after free (dangling pointer).
  • Losing the original pointer by writing p = realloc(p, ...) without checking — if realloc fails it returns NULL and you lose the old block.
🏋️ Practice

Ask the user for a number n, allocate an array of n integers with malloc, fill it with the first n even numbers, print them, and free it. Confirm there is exactly one free for your one malloc.

Summary

  • Dynamic memory lets a program request memory from the heap at run-time.
  • malloc allocates (garbage); calloc allocates and zeroes.
  • realloc resizes a block and may move it — reassign its result.
  • Every allocation needs a matching free, or you get a memory leak.
  • Check for NULL, and set pointers to NULL after freeing.

Frequently Asked Questions

What is dynamic memory allocation in C?
Dynamic memory allocation means asking for memory while the program is running, instead of fixing the size when you write the code. It uses functions like malloc and calloc to get memory from an area called the heap, and gives you a pointer to it. This lets your program handle amounts of data you did not know in advance.
What is the difference between malloc and calloc?
Both allocate memory on the heap, but malloc leaves the memory uninitialised (it contains garbage), while calloc sets every byte to zero. Also, malloc takes one total size argument, whereas calloc takes the number of elements and the size of each separately.
What is a memory leak in C?
A memory leak happens when you allocate memory with malloc or calloc but never call free on it. That memory stays reserved and unusable until the program ends. In long-running programs, repeated leaks slowly eat up all available memory.
What does realloc do in C?
realloc changes the size of a block you already allocated — for example growing an array when you need more room. It may move the block to a new location and return a new pointer, so you should always assign its result back and check it before using it.
What is a dangling pointer?
A dangling pointer is a pointer that still holds the address of memory that has already been freed. Using it leads to undefined behaviour and crashes. The safe habit is to set a pointer to NULL right after you free it, so it no longer points to released memory.
← Back to C Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.