Dynamic Memory Allocation in C

Introduction

Memory Allocation in C

In this post, we will learn about the dynamic allocation of memory in C. Also, we should be able to understand the pointers because we will be dealing with memory. To learn about pointers, please visit this link here.

Dynamic Memory Allocation in C

It requires dynamic memory allocation to create and maintain dynamic data structures. To put it differently, it is the ability for a program to obtain more memory space or to release space no longer needed at the time of execution.

Implementation of Dynamic Memory Allocation

In C, there are different functions related to memory allocation; malloc(), calloc(), realloc(), and free(). The functions are provided under the library stdlib.h. Furthermore, we need sizeof() operator to get the size of data type we will be allocating. The functions malloc(), calloc() and realloc() return a pointer of type void * to the allocated memory. Then, we can assign the pointer to any data type.

malloc()

malloc() or ‘memory allocation’ is used to dynamically allocate a single large block of memory. Also, it is the simplest type of memory allocation technique in C. For instance, if we want to allocate an integer array of length n, we can do the following:

arr = (int*) malloc(n * sizeof(int));

Now, let’s look into a complete example of malloc():

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

int main()
{
    int *arr, n;
    
    printf("Enter the number of items: ");
    scanf("%d", &n);
    
    arr = (int*) malloc(n * sizeof(int));
    
    if (arr != NULL) {
        printf("Memory successfully allocated!\n");
        int i;
        printf("Enter the numbers in the array: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d]: ", i);
            scanf("%d", arr + i);
            // scanf("%d", &arr[i]);    // Equivalently
        }
        printf("The numbers you entered are: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d] = %d\n", i, *(arr + i));
            // printf("arr[%d] = %d\n", i, arr[i]);     // Equivalently
            
        }
    }
    else {
        printf("Cannot allocate memory!\n");
        exit(0);
    }
    
    return 0;
}

calloc()

calloc or ‘contiguous allocation’ is used to dynamically allocate a number of blocks of memory and initialize each block with zero. In contrast to malloc(), calloc() clears the memory it allocates and malloc() does not. Similar to the example above, we can do the following to allocate an integer array of size n:

arr = (int*) calloc(n, sizeof(int));

As an illustration, let’s look at the example below:

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

int main()
{
    int *arr, n;
    
    printf("Enter the number of items: ");
    scanf("%d", &n);
    
    arr = (int*) calloc(n, sizeof(int));
    
    if (arr != NULL) {
        printf("Memory successfully allocated!\n");
        int i;
        printf("Enter the numbers in the array: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d]: ", i);
            scanf("%d", arr + i);
            // scanf("%d", &arr[i]);    // Equivalently
        }
        printf("The numbers you entered are: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d] = %d\n", i, *(arr + i));
            // printf("arr[%d] = %d\n", i, arr[i]);     // Equivalently
            
        }
    }
    else {
        printf("Cannot allocate memory!\n");
        exit(0);
    }
    
    return 0;
}

realloc()

Now, if we want to change the size of memory allocation in execution, we can use realloc(). Doing so, previous content will not be modified unless lower size is allocated. To explain this, let’s look at an example:

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

int main()
{
    int *arr, n, newN;
    
    printf("Enter the number of items: ");
    scanf("%d", &n);
    
    arr = (int*) calloc(n, sizeof(int));
    
    if (arr != NULL) {
        printf("Memory successfully allocated!\n");
        int i;
        printf("Enter the numbers in the array: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d]: ", i);
            scanf("%d", arr + i);
            // scanf("%d", &arr[i]);    // Equivalently
        }
        printf("The numbers you entered are: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d] = %d\n", i, *(arr + i));
            // printf("arr[%d] = %d\n", i, arr[i]);     // Equivalently
            
        }
    }
    else {
        printf("Cannot allocate memory!\n");
        exit(0);
    }
    
    printf("Enter the new number of items: ");
    scanf("%d", &newN);
    
    arr = realloc(arr, newN * sizeof(int));
    
    if (arr != NULL) {
        printf("Memory reallocated!\n");
        int i;
        printf("Enter new numbers: \n");
        for (i = n; i < newN; i++) {
            printf("arr[%d]: ", i);
            scanf("%d", &arr[i]);
        }
        printf("The total numbers including new are: \n");
        for (i = 0; i < newN; i++) {
            printf("arr[%d] = %d\n", i, arr[i]);
        }
    }
    else {
        printf("Cannot reallocate the memory!\n");
    }
   
    return 0;
}

free()

Up to this point, we learnt to allocate the memory. On the other hand, to deallocate the memory, we can use free() function as follows:

/******************************************************************************

                            Online C Compiler.
                Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.

*******************************************************************************/

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

int main()
{
    int *arr, n, newN;
    
    printf("Enter the number of items: ");
    scanf("%d", &n);
    
    arr = (int*) calloc(n, sizeof(int));
    
    if (arr != NULL) {
        printf("Memory successfully allocated!\n");
        int i;
        printf("Enter the numbers in the array: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d]: ", i);
            scanf("%d", arr + i);
            // scanf("%d", &arr[i]);    // Equivalently
        }
        printf("The numbers you entered are: \n");
        for (i = 0; i < n; i++) {
            printf("arr[%d] = %d\n", i, *(arr + i));
            // printf("arr[%d] = %d\n", i, arr[i]);     // Equivalently
            
        }
    }
    else {
        printf("Cannot allocate memory!\n");
        exit(0);
    }
    
    printf("Enter the new number of items: ");
    scanf("%d", &newN);
    
    arr = realloc(arr, newN * sizeof(int));
    
    if (arr != NULL) {
        printf("Memory reallocated!\n");
        int i;
        printf("Enter new numbers: \n");
        for (i = n; i < newN; i++) {
            printf("arr[%d]: ", i);
            scanf("%d", &arr[i]);
        }
        printf("The total numbers including new are: \n");
        for (i = 0; i < newN; i++) {
            printf("arr[%d] = %d\n", i, arr[i]);
        }
    }
    else {
        printf("Cannot reallocate the memory!\n");
    }
    // Free the memory
    free(arr);
    printf("Memory Freed!\n");
    return 0;
}

Conclusion on Memory Allocation in C

In a nutshell, it is a better practice to allocate memory in runtime rather than statically allocate during execution. However, it must be remembered to free the allocated memory to limit the wastage of memory.

You can visit my github profile here: http://github.com/mrkrishnaupadhyay

I am a Computer Engineer from Pulchowk Campus, IOE. I love programming, and music. Python, Java, Php, Javascript, Django, Laravel, Spring, express.js, etc. are my specialities.

1 Comment

Leave a Reply

%d bloggers like this: