Dynamic Memory Allocation In C: Complete Guide

Dynamic memory allocation in C

“Dynamic Memory Allocation in C” is a core concept that every serious C programmer must understand. In C, memory management is completely in the hands of the programmer.

If you do not handle memory properly, your program may waste space or behave unpredictably. C provides special functions like malloc(), calloc(), realloc(), and free() to manage dynamic memory.

These functions work with heap memory and require careful handling. Once you understand this concept clearly, you will write more efficient and professional C programs. So, let us go through them.

TL; DR: Dynamic Memory Allocation In C

Aspect

Summary

What Is It?

It is a process of allocating memory at runtime instead of compile time to avoid memory wastage. This prevents unused memory when the input size is unknown.

Key Functions

Malloc(), Calloc(), Free(), Realloc() from <stdlib.h> library.

Malloc()

It allocates a single block of memory where the values are uninitialized or garbage.

Calloc()

This is somehow similar to malloc(), but it allocates multiple blocks and initializes memory to zero.

Realloc() and Free()

The free() releases memory, whereas the realloc() resizes existing memory during execution.

What Is Dynamic Memory Allocation In C Programming?

Dynamic Memory Allocation refers to the process of allocating memory during the execution of a program rather than at compile time. In C, arrays normally require a fixed size to be declared in advance.

However, in many real-world scenarios, a programmer may not know beforehand how much memory will be required. This limitation of fixed-size arrays makes memory management challenging.

Visual representation showing the importance of Dynamic Memory Allocation in C using the array with fixed length

If a programmer declares a large array to avoid a shortage, a significant portion of memory may remain unused, leading to wastage of system resources. On the other hand, if a smaller array is declared and the data exceeds its capacity, then it can cause overflow issues.

Dynamic memory allocation solves this problem by allowing memory from the heap at runtime, exactly when it is needed. The memory can also be resized or released when it is no longer required.

 

Why Students Find Dynamic Memory Allocation In C Difficult?

From my experience in mentoring, I have seen many students struggle with Dynamic Memory Allocation because it introduces manual memory management, which is very different from other modern languages.

In C, you are fully responsible for allocating and freeing memory correctly. One small mistake can lead to crashes, memory leaks, or undefined behaviour. This is the main reason behind all the confusion.

Here, I am listing down some more reasons that I believe confuse students.

1) Stack Vs Heap Is Not Visually Clear: 

The major reason is that students don’t find the difference between the stack and the heap. They hear about “stack memory” and “heap memory,” but the logic has never been clear to them. Since both store variables, it feels like unnecessary theory.

				
					#include <stdlib.h>
int main() {
    int x = 10; // Stored in stack memory
    int *ptr = malloc(sizeof(int)); // Memory allocated in heap
    *ptr = 20; // Assign value to heap memory
}
				
			

Both ‘x’ and ‘*ptr’ store integers, so they look similar. But students don’t realize that one is automatically managed by the stack and the other must be manually handled because it gets stored in the heap.

2) Pointers Add An Extra Layer Of Confusion:

Dynamic memory allocation always involves pointers. Many students already struggle with pointers, so combining them with malloc() increases confusion.

				
					#include <stdlib.h>
int main() {
    int *ptr = malloc(sizeof(int));  // ptr stores address
    *ptr = 50; // accessing value at that address
    return 0;
}

				
			

Students mix up ‘ptr’, which is the address, and ‘*ptr’, which is the value. This misunderstanding makes dynamic allocation feel unpredictable.

3) Forgetting To Free Memory Doesn’t Show Immediate Errors:

Unlike syntax errors, memory leaks don’t immediately crash small programs. So students don’t understand why free() is important. And this small assumption causes bug troubles in the future.

				
					#include <stdlib.h>
int main() {
    int *arr = malloc(5 * sizeof(int));  // Allocate array
    // We are somewhere used the array
    free(arr); // Release heap memory
    return 0;
}

				
			

If ‘free(arr)’ is removed, the program may still run fine. But the memory will still be occupied after the end of the program. Because the mistake isn’t instantly visible, students underestimate its importance.

 

The Memory Layout In C Language: The Stack And Heap

Before we move deeper into Dynamic Memory Allocation in C, it is important to understand how memory is organized in a C program. The memory layout mainly consists of two important areas.

They are the Stack and the Heap. Having a clear idea about these two sections will make the concept of memory management much easier to understand.

  • Stack: Stack memory is used to store local variables and manage function calls. Whenever a function is called, its variables are pushed onto the stack. Once the function finishes execution, that memory is automatically removed.
  • Heap: Heap memory is used for Dynamic Memory Allocation. Unlike the stack, memory in the heap is not managed automatically. It must be allocated and freed manually by the programmer using functions like malloc() and free().

In simple terms, the Stack is used for Static Memory Allocation that happens automatically, while the Heap is used for Dynamic Memory Allocation that requires manual control.

Criteria

Static Memory Allocation

Dynamic Memory Allocation

Allocation Time

Compile Time

Runtime

Memory Size

Fixed

Flexible

Location

Stack

Heap

Management

Automatic

Manual

Example

int arr[10];

int *arr = malloc()

What Are The Methods To Do Dynamic Memory Allocation?

In the C programming language, we can facilitate the process of dynamic memory allocation using 4 library functions. These 4 library functions are:

  • Malloc()
  • Calloc()
  • realloc()
  • free()

Let’s also get to know how we can use the above 4 functions with the help of example codes.

Dynamic memory allocation in C relies heavily on pointers, a variable that stores memory addresses. If you want to strengthen your understanding of pointers and how they work under the hood, this guide on Types of Pointers in C++ offers clear explanations and examples.

 

How To Do Dynamic Memory Allocation In C Using Malloc()?

The malloc() or ‘memory allocation’ function in C allocates a single memory block of a set size. This block initially contains some garbage value. By default, it returns a pointer of the type void.

Visual representation showing the syntax of malloc() and the 4 bytes dynamic memory allocation

When To Use Malloc():

  • Use malloc() when you need to allocate a block of memory at runtime, and you already know the total number of bytes required.
  • Use it when you want faster allocation, and you don’t need the memory to be initialized to zero.
  • Use malloc() when creating dynamic arrays, structures, or linked list nodes where you will manually assign values after allocation.

General Syntax: p = (int)*malloc(n*sizeof(int));

				
					#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *arr;
    int n, i;
    printf("\t\t\t Dynamic Memory Allocation using malloc() \n");
    printf("How many numbers do you want to enter? \n");
    scanf("%d", &n);
    // allocating memory for n integers
    arr = (int *)malloc(n * sizeof(int));
    if(arr == NULL){
    printf("Memory cannot be allocated!");
    }
    else{
            for(i=0; i<n; i++){
            printf("Enter element at arr[%d] \n", i);
            scanf("%d", (arr+i));
            }
            printf("\n Entered numbers are...\n");
            for(i=0; i<n; i++){
                printf("%d ",*(arr+i));
        }
    }
}

				
			

Steps Of The Program:

  1. First, take one integer pointer that will be used to get the initial address of the malloc() block.
  2. By taking the input number from the users, make a specific number of blocks inside the memory.
  3. Make a conditional statement to catch the faulty insertion of the users.
  4. Implement a for loop to take data from the users & insert it into the array.
  5. Using another for loop, check all the elements & print them.

Output:

Output image of Dynamic Memory Allocation in C using malloc() where 5 elements are entered by the user

 

How To Do Dynamic Memory Allocation In C Using Calloc()?

Another way to facilitate dynamic memory allocation in C is by using Calloc() or the ‘contiguous allocation’ function.

The Calloc() function allocates multiple blocks of memory for storing variables and returns a pointer of type void, which can be cast to the type the user wants.

Image showing the use of dynamic memory allocation calloc() function along with its syntax and implication in memory

The Calloc() function also initializes the blocks to zero. Hence, unlike malloc(), no garbage value is present in the memory blocks.

When To Use Calloc():

  • Calloc() should be used when you need to allocate memory for multiple elements and want all values automatically initialized to zero.
  • Use it when working with arrays of integers, floats, or structures where default zero values prevent garbage data issues.
  • Use calloc() when safety and clean initialization are more important than minor performance differences.

General Syntax:  p = (caste type)*calloc(n, size);

				
					#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *arr;
    int n, i;
    printf("\t\t\t Dynamic Memory Allocation using calloc() \n");
    printf("\n How many numbers do you want to enter? \n");
    scanf("%d", &n);
    // allocating memory for n integers
    arr = (int *)calloc(n, sizeof(int));
    if(arr == NULL){
    printf("Memory cannot be allocated!");
    }
    else{
            for(i=0; i<n; i++){
                 printf("Enter element at arr[%d] \n", i);
                 scanf("%d", (arr+i));
            }
        }
        printf("\n Entered numbers are...\n");
            for(i=0; i<n; i++){
            printf("%d ",*(arr+i));
         }
    return 0;
}
				
			

Steps Of The Program:

  1. In this case, an integer pointer is declared that is going to accept the initial address of the calloc() block.
  2. Now, implement the calloc() statement using the above syntax for a specific number of elements.
  3. Using the for loops, the data will be inserted into the array. And another for loop will be implemented to print all of them.

Output:

Output screenshot for Dynamic Memory Allocation in C using calloc() fucntion where we are allocating 5 elements in array

 

Performance Comparison Table Between Malloc() And Calloc():

Most students get confused between the malloc() and calloc() functions. Sometimes, they use malloc() in place of calloc() and vice versa. To avoid such a scenario, here is the comparison table between them.

Criteria

Malloc()

Calloc()

Allocation

Faster

Slower

Initialization

Uninitialized

Zeroed

Memory State

Garbage

Clean

Parameter

Single

Double

Performance

Better

Lower

How To Do Dynamic Memory Allocation In C Using Realloc()?

We use the realloc() function in C to ‘re-allocate’ or re-size the memory block that was previously allocated by using the malloc() or calloc() functions. If the already existing memory block is insufficient, then that can be reshaped with the help of the realloc() function.

An image showing the syntax of realloc() and comparing it with malloc() function as well as from the memory perspective

When To Use Realloc():

  • Use realloc() when you need to increase or decrease the size of previously allocated memory.
  • It should be used when you start with a small dynamic array and later realize you need more space based on user input.
  • Use realloc() carefully when resizing buffers, ensuring you store the returned pointer properly to avoid memory loss.

General Syntax: p = realloc(p, Newsize);

				
					#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *arr;
    int n, i, add;
    printf("\t\t\t Dynamic Memory Allocation using realloc() \n");
    printf("\n How many numbers do you want to enter? \n");
    scanf("%d", &n);
    // allocating memory for N integers
    arr = (int *)calloc(n, sizeof(int));
    if(arr == NULL){
    printf("Memory cannot be allocated!");
    }
    else{
            for(i=0; i<n; i++){
                 printf("Enter element at arr[%d] \n", i);
                 scanf("%d", (arr+i));
            }
            printf("\n Entered numbers are...\n");
            for(i=0; i<n; i++){
            printf("%d ",*(arr+i));
         }
        }
        printf("\n How many more numbers do you want to add? \n");
        scanf("%d", &add);
        // reallocation of memory
        arr = realloc(arr, (n + add) * sizeof(int));
        for(i=n; i<n+add; i++){
             printf("Enter element: \n");
             scanf("%d", (arr+i));
        }
            printf("\n Entered numbers are...\n");
            for(i=0; i<n+add; i++){
                printf("%d ",*(arr+i));
        }
}

				
			

Steps Of The Program:

  1. First, in the program, the memory allocation will be done with the help of the malloc() function.
  2. Now, in the same manner, the data will be taken & it will be printed inside the program.
  3. Suppose there is a need to insert two elements in the program. So, the realloc() function is implemented with the same malloc() size.
  4. But the new size that should be added is summed there. It will increase the space.
  5. Now, the number of elements will be added & printed in the program.

Output:

An image showing the output result of Dynamic Memory Allocation in C using realloc() where we are allocating 2 more elements on 5 earlier elements

 

What Is The Purpose Of Free() In Dynamic Memory?

The free() function does the opposite of malloc() and calloc(). Unlike the malloc() or calloc() function, free() actually ‘de-allocates’ the previously allocated memory. This means that the function helps in freeing and reducing memory. This memory can be used later in the program.

Image showing the purpose of dynamic memory deallocation function free() which is erasing memory created by malloc()

When you allocate memory manually, forgetting to release it later can cause memory leaks, small mistakes that pile up and crash your program. To learn how leaks happen and how to avoid them, check out How Memory Leaks Happen and How to Avoid Them.

When To Use Free():

  • Use free() whenever dynamically allocated memory is no longer needed.
  • Use it to prevent memory leaks, especially inside loops or long-running programs.
  • Always use free() before a pointer goes out of scope if that memory was allocated using malloc(), calloc(), or realloc().

General Syntax: free(p); Here, ‘p’ is the variable that was previously allocated to the memory.

				
					#include<stdio.h>
#include<stdlib.h>
int main()
{
    int *arr;
    int n, i;
    printf("\t\t\t Dynamic Memory Allocation - De-allocation using free() \n");
    printf("\n How many numbers do you want to enter? \n");
    scanf("%d", &n);
    // allocating memory for N integers
    arr = (int *)calloc(n, sizeof(int));
    if(arr == NULL){
    printf("Memory cannot be allocated!");
    }
    else{
            for(i=0; i<n; i++){
                printf("Enter element at arr[%d] \n", i);
                scanf("%d", (arr+i));
            }
            printf("\n Entered numbers are...\n");
            for(i=0; i<n; i++){
                printf("%d ",*(arr+i));
            }
        }
        //free memory
        free(arr);
        printf("\n\nMemory Freed!");
}
				
			

Steps Of The Program:

  1. Suppose one dynamic memory is allocated using the calloc() method. The implementation process is the same as we have done above.
  2. Now, the data is also printed in the program using a for loop & some statements.
  3. Now, using the above syntax, we are going to remove the complete pointer that holds the initial address of the block. It will remove the block itself from the computer memory.
  4. At last, one statement is implemented to show that the program executed completely.

Output:

Output screenshot for Dynamic Memory Allocation in C using free() where we are deallocating 5 elements from array

 

When Not To Use Dynamic Memory Allocation In C Programming?

Over the years, I have seen many students assume that Dynamic Memory Allocation is always the better option. That is not true. Just because you can use heap memory in C does not mean you should always use it.

As a developer, your job is to choose the simplest and safest solution for the problem. Here are situations where you should avoid Dynamic Memory Allocation.

  • When the data size is fixed and known in advance, never use the dynamic memory allocation technique.
  • It should be avoided when working with small programs or beginner-level questions, where static arrays will be simple to use.
  • Avoid using dynamic memory allocation when performance is extremely critical, because stack allocation is faster than heap allocation.
  • Don’t go for it when you are not confident about managing memory properly, since forgetting to call free() can cause memory leaks.
  • When writing embedded systems or low-level applications with limited memory, you should avoid it because dynamic allocation may not be safe or allowed.

Mentor Advice: Use Dynamic Memory Allocation only when flexibility is truly required. Otherwise, keep it simple and stick to static memory.

 

What Are Some Real-World Usage Of Dynamic Memory Allocation?

While mentoring students in C programming, I have noticed that students often assume that dynamic memory allocation is only taught for educational purposes.

To remove such assumptions from their mind, I usually list down the real-world usage of it. Here is the list that I usually give to my students.

  • It is used to manage processes and system resources dynamically in Operating Systems.
  • In Database Systems, it helps to store and retrieve large, variable-sized data efficiently.
  • In File Handling Programs, allocation of memory based on file size at runtime is done by it.
  • To build syntax trees and symbol tables dynamically in different compilers, this method is used.
  • If you want to work on linked lists, stacks, queues, and trees, dynamic memory allocation will be needed.

 

Common Mistakes Students Make In Dynamic Memory Allocation:

While dealing with Dynamic Memory Allocation in C programming, there are some serious mistakes that students often commit in their exams. Let us check some such common mistakes.

  • Sometimes, we dynamically allocate new memory, but forget to free it. This creates a memory shortage, and hence, we will experience the Memory Leaks issue.
  • Sometimes, a pointer that has the address of the memory has been freed, but we don’t remove the pointer and still try to use it. This causes the Dangling Pointer Error.
  • Dynamic Memory Allocation sometimes might not create the memory. But we assume memory has been created and start work on it, which causes such issues.
  • Sometimes, when we try to free a dynamically created memory that was already freed earlier, this results in the Double Free Error issue in our code.
  • Sometimes, we mix up the Stack and Heap memories. We treat dynamically created memories like local variables, which creates all the problems.

Conclusion:

“Dynamic Memory Allocation in C” is a fundamental concept that every C programmer should master. It gives you control over memory and helps you write flexible programs.

Without understanding it, handling advanced topics becomes difficult. This concept becomes especially important when working with data structures like linked lists, stacks, queues, and trees.

If you truly want to improve in C, focus on practicing dynamic memory allocation regularly. Write programs, test edge cases, and make sure you free allocated memory properly.

 

Key Takeaways:

  • Dynamic Memory Allocation helps to allocate memory without losing any memory space.
  • Using Malloc(), Calloc(), and Realloc() functions, we can dynamically allocate memory.
  • To remove the created memory spaces, the Free() function should be used.
  • Memory Leaks, Dangling Pointers, Double-free, etc., are some common mistakes in this case.
  • From Operating Systems to File Management, the use of dynamic memory allocation is everywhere.

 

Frequently Asked Questions:

1) What is heap fragmentation in C programming?

Heap fragmentation is a problem where the free memory in the heap gets broken into smaller parts due to frequent memory Allocation and Deallocation. These small memory segments will become unusable.

2) How to avoid memory leaks in C?

Memory leaks are one of the common mistakes in Dynamic Memory Allocation. To avoid this, we have to use the free() function to remove every memory block that is no longer in use.

3) What happens if Malloc() returns NULL?

The Malloc() can sometimes return Null as the result. If the Dynamic Memory Allocation is unsuccessful, then it can return Null. This is a very rare situation to have a Null from Malloc().