Back to C Programming
2026-07-155 min read

Example: malloc() and free()

Learn Example: malloc() and free() step by step with clear examples and exercises.

Why This Matters

Dynamic memory allocation is a crucial skill for C programmers as it allows them to manage memory during runtime, avoiding the fixed size limitation of arrays. Understanding malloc(), calloc(), free(), and realloc() functions will help you create more efficient and flexible programs. These functions are often used in real-world scenarios, such as creating dynamic data structures like linked lists or handling user input dynamically.

Knowing how to use these functions effectively can also help you avoid common memory leaks and segmentation faults that may occur during program execution. In addition, understanding dynamic memory allocation is essential for competitive programming contests and job interviews where memory efficiency is a critical factor.

Prerequisites

Before diving into the core concept, it's important to have a good understanding of the following topics:

  1. Basic C syntax and control structures (if, for, while)
  2. Pointers in C
  3. Data types (int, char, float, etc.)
  4. File I/O (stdin, stdout, FILE*)

Core Concept

Dynamic memory allocation in C is achieved through four functions: malloc(), calloc(), free(), and realloc(). These functions are defined in the standard library header file stdlib.h.

malloc()

malloc() is used to allocate a block of memory of a specified size, measured in bytes. The syntax for using malloc() is as follows:

void *ptr = malloc(size);

Here, size is the number of bytes you want to allocate, and ptr is a pointer that will hold the address of the allocated memory block. The returned pointer may be cast to any data type, but it should be stored in a variable of type void*.

calloc()

calloc() is similar to malloc(), but it initializes the allocated memory to zero. This can be useful when you want to create an array with pre-initialized values:

void *ptr = calloc(nmemb, size);

Here, nmemb is the number of elements you want to allocate, and size is the size of each element in bytes. The returned pointer has the same considerations as with malloc().

free()

Once you've finished using a block of memory allocated with malloc() or calloc(), it should be deallocated to avoid memory leaks:

free(ptr);

Here, ptr is the pointer to the memory block that was previously allocated. It's essential to free memory in a timely manner to prevent your program from running out of memory and crashing.

realloc()

realloc() allows you to change the size of a previously allocated memory block:

ptr = realloc(ptr, new_size);

Here, ptr is the original pointer to the memory block, and new_size is the desired size of the memory block after resizing. If ptr was originally NULL, it will behave like a call to malloc().

Worked Example

Let's create a simple program that allocates an array of integers using calloc(), fills it with values, and then prints the contents:

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

int main() {
int n = 5;
int *arr;
int i;

// Allocate an array of integers and initialize it to zero
arr = calloc(n, sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}

// Fill the array with values
for (i = 0; i < n; ++i) {
arr[i] = i * i;
}

// Print the contents of the array
printf("Array: ");
for (i = 0; i < n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");

// Free the allocated memory
free(arr);

return 0;
}

When you run this program, it will output:

Array: 0 1 4 9 16

Common Mistakes

  1. Forgetting to include stdlib.h header file: Remember to include the standard library header file at the beginning of your C program to access dynamic memory allocation functions.
  1. Not checking for NULL pointers: Always check if the returned pointer from malloc(), calloc(), or realloc() is NULL before using it, as it may indicate a failure in memory allocation.
  1. Leaking memory: Make sure to free allocated memory when you're done using it to avoid memory leaks.
  1. Not initializing pointers: Before using a pointer, make sure it's been initialized to NULL or another appropriate value to prevent undefined behavior.
  1. Misusing realloc(): Be careful when resizing a memory block with realloc(), as the contents of the original memory block may be lost if the new size is smaller.

Practice Questions

  1. Write a program that uses malloc() to allocate an array of 10 integers, fills it with values from 1 to 10, and then prints the sum of all elements.
  2. Create a program that uses calloc() to create a 3x3 matrix of zeros, fills it with user input, and then calculates and prints the determinant of the matrix.
  3. Write a program that dynamically allocates memory for an array of strings using malloc(), reads lines from a file, stores them in the array, and then frees the allocated memory after printing the contents.

FAQ

Q: Why should I use dynamic memory allocation instead of fixed-size arrays?

A: Dynamic memory allocation allows you to create arrays or other data structures with a size that can change during runtime, making your code more flexible and efficient in handling different input sizes.

Q: What happens if I try to free already freed memory using free()?

A: Attempting to free already freed memory will result in undefined behavior, which may include crashing the program or causing unexpected results.

Q: Why do I need to check for NULL pointers when using dynamic memory allocation functions?

A: Checking for NULL pointers helps you handle cases where the requested memory could not be allocated, allowing your program to gracefully handle such errors instead of crashing.

Q: What is the difference between malloc() and calloc()?

A: The main difference between malloc() and calloc() is that calloc() initializes the allocated memory to zero, while malloc() does not. This can be useful when you want to create an array with pre-initialized values.

Q: When should I use realloc() instead of malloc() or calloc()?

A: You should use realloc() when you need to change the size of a previously allocated memory block without copying its contents. This can be useful for growing or shrinking arrays dynamically during runtime.