What is Dynamic Memory Allocation in C?

In Programming languages such as C and C++, Programming generally has two stages-Compilation and Execution (Run time). All the tasks such as including the header file, and assigning memory blocks to variables are done during the compilation, and the execution occurs during the run time.

But, this approach has a drawback. As the memory to variables is assigned during the compile time, it cannot be altered or resized later. This is called static memory allocation. In this article, we will see the drawback of static memory allocation and what is Dynamic Memory Allocation in C.

First, let’s see the Static Memory Allocation in C. The following source code shows an integer array of size 8 has been declared but values are assigned only till index 5. Since the array is declared statically, you cannot change its size from 8 to 5. Thus, the memory assigned to the remaining 3 indices is wasted.

#include<stdio.h>
#include<conio.h>
int main(){
    int arr[8];//array of five elements
    for(int i=0;i<5;i++){
        arr[i]=i+1; //assigning the elements to array till index 5
    }
    for(int i=0;i<8;i++){
        printf("%d ", arr[i]) ;
    }
}

When you try to access the array elements, the 3 empty indices are assigned garbage value by default as shown in the output.

Array elements are: 1 2 3 4 5 4200939 4200848 0

write your code here: Coding Playground

So, to overcome this challenge, you have to understand what is Dynamic Memory Allocation in C. There are some inbuilt functions defined in the “stdlib.h” header file that facilitates this concept.

Dynamic Memory Allocation in C simply refers to changing the allocated size of the Data Structure during the run time. It often happens that a programmer doesn’t know how much memory would be needed to store the information in the Data Structure while writing the code.

Therefore, it is crucial to know about dynamically allocating the memory so, that there is no overhead of tracking the memory assigned to the Data Structure beforehand.

In C, the following four inbuilt functions play a crucial role in Runtime memory allocation:

  • Malloc-Allocates a single block of memory
  • Calloc- Allocate multiple blocks of memory
  • Realloc- It reassigns the memory allocated by malloc() or calloc()
  • Free- It releases the dynamically allocated memory

To understand how these functions work, you should know about the concept of Pointers in C. [internal link can be given].

Now, let’s see how these functions work for runtime memory allocation.

Malloc() Function in C:

Malloc stands for ‘Memory Allocation.’ This function allocates a single block of memory of the required size. It returns the pointer of a void type which is type-casted to any form. The syntax of malloc() is:

ptr=(cast type*)malloc(sizeof(size of bytes))

Initially, the memory block is assigned a garbage value. Also, if the memory is not available, the malloc() function returns a null pointer.

The following code shows the implementation of C malloc().

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int main(){
    int n;
    int* pointer;
    printf("Enter size of array\n"); //taking size from user
    scanf("%d", &n);
    pointer = (int*)malloc(n* sizeof(int)); // memory block allocated
    printf("Enter elements\n");
    for(int i=0;i<n;i++){
        scanf("%d", pointer+i);
    }
    printf("size of memory block is ");
printf("%d\n", _msize(pointer)); //_msize tells memory allocated by malloc
// printf("%d", sizeof(n));
    printf("the elements entered are\n");
    for(int i =0;i<n;i++){
        printf("%d\n", *(pointer+i));
    }
}

Following is the output of the code:

Enter size of array
5
Enter elements
1
2
3
4
5
size of memory block is 20
the elements entered are
1
2
3
4
5

write your code here: Coding Playground

Since the size of an integer in a 64-bit compiler is 4 bytes and the total number of elements is 3, the size of the block is 12 bytes.

Calloc() Function in C:

Calloc stands for ‘contiguous allocation.’ This function is similar to the malloc() function for Dynamic Memory Allocation in C. The difference is that it allocates multiple blocks memory blocks of the desired size. If the memory is insufficient, it returns a null pointer.

The syntax for calloc() function is

ptr=(cast-type*)calloc(n, sizeof(type))

The following code represents the implementation of calloc() function for Dynamic Memory Allocation in C.

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int main(){
//_msize()
    int n;
    int* pointer;
    printf("Enter number of blocks required\n");
    scanf("%d", &n);
    pointer = (int*)calloc(n, sizeof(int)); // memory block allocated using calloc
    printf("Enter elements\n");
    for(int i=0;i<n;i++){
        scanf("%d", pointer+i);
    }
    printf("size of memory block is ");
printf("%d\n", _msize(pointer));
// printf("%d", sizeof(n));
    printf("the elements entered are\n");
    for(int i =0;i<n;i++){
        printf("%d\n", *(pointer+i));
    }

}

After execution of this code, you will get the following output. Here, calloc() allocates 5 blocks each of size 4 bytes (integer). Thus, the total memory is 20 bytes.

Output:

Enter number of blocks required
5
Enter elements
1
34
23
56
57
size of memory block is 20
the elements entered are
1
34
23
56
57

write your code here: Coding Playground

Realloc() Function:

After knowing what is Dynamic Memory Allocation in C using malloc and calloc, it may be possible that the memory assigned becomes insufficient. In such a case, the realloc() function is used to allocate new memory blocks. It maintains the previous memory blocks and adds new blocks by initializing them with garbage values. The syntax of the realloc() function is:

ptr=realloc(ptr, newSize)

The following code shows how to use the realloc() function for dynamic memory allocation.

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
int main()
{
    int *pointer = (int *)malloc(3 * sizeof(int));
    printf("Before Reallocation, size is 3\n");
    for (int i = 0; i < 3; i++)
    {
        pointer[i] = i + 1;
    }

    printf("Elements are \n");

    for (int i = 0; i < 3; i++)
    {
        printf("%d \n", pointer[i]);
    }

    // using realloc function
    pointer = (int *)realloc(pointer, 6 * sizeof(int));
    printf("After reallocation: size is 6\n");

    for (int i = 0; i < 6; i++)
    {
        pointer[i] = i + 1;
    }

    printf("Elements are \n");

    for (int i = 0; i < 6; i++)
    {
        printf("%d \n", pointer[i]);
    }
}

The output of the following code is:

Before Reallocation, size is 3
Elements are
1
2
3
After reallocation: size is 6
Elements are
1
2
3
4
5
6

write your code here: Coding Playground

Free() Function in C:

Free Function is used to release the dynamic memory allocated memory. There can be instances in which the system memory becomes insufficient as all the memory is allocated. So, the memory assigned to the unused pointers to memory blocks can be made free using this function. The following code shows the use of the free function. It takes the pointer variable as an argument.

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int main()
{
    int *pointer = (int *)malloc(3 * sizeof(int));
    int start = 100;
    for (int i = 0; i < 3; i++)
    {
        pointer[i] = start + i;
    }


    printf("Before calling free function, size of memory block is ");
    printf("%d\n", _msize(pointer));

//calling free function
    free(pointer);
 
    printf("After calling free function, size of memory block is ");
    printf("%d\n", _msize(pointer));
}

The output shows that after calling the free function, all the memory allocated using Dynamic Memory Allocation in C is released.

Before calling free function, size of memory block is 12
After calling free function, size of memory block is -1

write your code here: Coding Playground

Now, you have learned, what is Dynamic Memory Allocation in C using calloc(), malloc(), and realloc() and how to release the dynamically allocated memory using the free() function.