Dynamic Memory allocation in C

In C, Dynamic array allocation is to allocate memory at runtime or during program execution. Basically, for variables, arrays, structure etc., memory is allocated at compile time.

Disadvantage of compile time memory allocation

  1. Allocated Memory size is fixed, due to this, memory size cannot be changed.
  2. For example, In array, array size is 5, it means only 5 elements can be added in array, Suppose, 3 elements are added, then 3 blocks of array is occupied and 2 blocks of array is wasted, and another example is, array size is 5 and need to add 8 elements, because of array size, it is not possible to add more elements to array with compile time memory allocation.

In above given points, to allocate or reallocate memory in C, as per requirement, Dynamic memory allocation is used and it is achieved by using pointers.

Advantage of Dynamic memory allocation

Memory size is allocated at runtime, hence memory size can be changed(add or remove) during program execution.

How to implement Dynamic memory allocation in C

C provides 4 different types of dynamic memory allocation function to allocate or free memory. These function are in <stdlib.h> header file.

mallac()Memory allocation
calloc()Contiguous Memory allocation
realloc()Reallocate memory
free()Free or release occupied memory

malloc()

It allocates memory of given size during runtime.

Syntax

<pointer_variable> = (data-type*) malloc(size)

Example

int *pntr;
pntr = (int*) malloc(int);

For more size of memory, multiply the number with size of data type.

int *pntr;
pntr = (int*) malloc(10 * sizeof(int));
  1. malloc accepts a single parameter, which specifies the number of bytes(size) allocated during runtime. It can be of any data type.
  2. In malloc, size must be provided using sizeof() function.
  3. malloc returns void* which holds the address of memory allocated.
  4. void* can be cast to any data type.
  5. malloc does not initialize memory, allocated memory contains garbage value.
  6. If malloc fails to allocate memory, it returns NULL pointer.

Example

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

int main()
{

    int *pntr;
    int no_of_elements, i;

    printf("Please Enter number of elements:");
    scanf("%d",&no_of_elements);
    printf("Number of elements are: %d\n", no_of_elements);

    pntr = (int*)malloc(no_of_elements * sizeof(int));
    
    // Store elements in pointer array
     for (i = 0; i < no_of_elements; i++) {
          pntr[i] = i + 1;
     }

        // Print the elements of the  pointer array
        printf("The elements of the array are: ");
        for (i = 0; i < no_of_elements; i++) {
            printf("%d, ", pntr[i]);
        }

    return 0;
}

calloc()

It also allocates contiguous (one after another block) memory at runtime. It accepts two parameters.

  1. number of elements.
  2. size of element or data type using sizeof() function.
  1. On memory allocation, returns the address of first byte.
  2. It initializes memory and does not contain garbage value.
  3. Returns NULL pointer, if memory allocation fails.

Declare calloc()

Syntax

<pointer_variable> = (data-type*) calloc(no_of_elements, size)

Example

int *pntr;
pntr = (int*) calloc(10, sizeof(int);

Complete Example

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

int main()
{
    int* pntr;
    int no_of_elements, i;

    printf("Enter number of elements: "); 
    scanf("%d",&no_of_elements);

    pntr = (int*)calloc(no_of_elements, sizeof(int));

    // Store elements in pointer array
     for (i = 0; i < no_of_elements; i++)
     {
         ptnr[i] = i;
     }

    // Print the elements of pinter array
    for (i = 0; i < no_of_elements; i++)
    {
        printf("\n%d, ", pntr[i]);
    }
    
    return 0;
}

realloc()

In C, it is used to reallocate already allocated memory, means realloc() can add or remove memory at runtime. it Initializes new memory blocks with garbage value. It accepts two parameters.

pntrPointer of malloc or calloc.
new_sizeThe number of bytes needs to be allocated.

Syntax

void *realloc(pntr, new_size);

Example

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

int main()
{
    int* pntr;
    int no_of_elements, i;

    printf("Enter number of elements: ");
    scanf("%d", &no_of_elements);

    // Dynamically allocate memory using calloc()
    pntr = (int*)calloc(n, sizeof(int));

    // store elements in pntr array
     for (i = 0; i < no_of_elements; i++) 
     {
          ptr[i] = i;
     }

     // Print the elements of the array
     printf("The elements of the array are: ");
     for (i = 0; i < no_of_elements; i++) 
     {
         printf("\n%d, ", pntr[i]);
     }

      // Get the new size for the array
      printf("\nEnter the new size for array: %d", no_of_elements);
      scanf("%d", &no_of_elements);

      // Re-allocating memory using realloc()
      pntr = (int*)realloc(pntr, no_of_elements * sizeof(int));
      
      if (pntr == NULL)
      {
         printf("Reallocation Failed\n");
         exit(0);
      }

      // Again store values in reallocated memory
      for (i = 5; i < no_of_elements; i++)
      {
            pntr[i] = i;
      }

      // Print the elements of the array
      printf("The elements of the array are: ");
      for (i = 0; i < no_of_elements; i++) 
      {
          printf("\n%d, ", pntr[i]);
      }
 return 0;
}

free()

In C, free() is used to release allocated memory by malloc(), calloc() or realloc() function because they can only allocate memory, cannot deallocate memory.

Syntax

free(pntr)

Here, pntr is pointer variable of malloc(), calloc() or realloc().

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

int main()
{
    int *pntr, *pntr1;
    int no_of_elements, i;

    printf("Please Enter number of elements:");
    scanf("%d",&no_of_elements);
    printf("Number of elements are: %d\n", no_of_elements);

    pntr = (int*)malloc(no_of_elements * sizeof(int));
    
    // Free allocated memory
    free(pntr);

    pntr1 = (int*)calloc(no_of_elements, sizeof(int));
   
    // Free allocated memory
    free(pntr1);

    return 0;
}

It is a good practice to release allocated Memory using free().