C Dynamic Memory Allocation : malloc(), calloc(), realloc()

The process of allocating memory at runtime is known as dynamic memory allocation. The concept of dynamic memory allocation in C language enables the user to allocate memory at runtime during the program execution.

There are four library routines known as "Memory Management Functions" that can be used for allocating and freeing memory during program execution. These functions helps the programmers to build complex application programs that use the available memory intelligently. These functions are :

Function Name Description
malloc() Allocates single block of requested memory.
calloc() Allocates multiple block of requested memory.
realloc() Reallocates the memory previously allocated by malloc() or calloc() functions.
free() Free previously allocated memory space.

malloc() Function :

The malloc() function allocate a block of memory and returns a pointer of it. But it does not initialize the memory during program execution, so it contains garbage values initially. The syntax of malloc() is :
 ptr = (cast-type *)malloc(byte-size);
At here, ptr is pointer of cast-type. The malloc() function returns a pointer (of cast-type) to an area of memory with size byte-size. For example :
 ptr = (int *)malloc(sizeof(int));
On successful execution of above statement, a memory space of size of 4 byte (int = 4 byte) is reserved and the address of the first byte of the memory allocated is assigned to the pointer ptr of type int. similarly,
 ptr = (char *)malloc(20);
The above statement allocates 20 bytes of space and assigned to the character pointer ptr. Also note that the storage space allocated dynamically has no name and therefore its content can be accessed only through the pointer.

Example 1 :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int *ptr;
  char *cptr;

  ptr = (int *)malloc(sizeof(int));
  if(ptr == NULL) {
 printf("!! Unable to allocate memory.\n");
 exit(1);
  }
  
  *ptr = 100;
  printf("%d\n", *ptr);

  cptr = (char *)malloc(30);
  
  if(cptr == NULL) {
 printf("!! Unable to allocate memory.\n");
 exit(1);
  }
  
  strncpy(cptr, "Hello world This is malloc()", 30);
  printf("%s\n", cptr);
  return 0;
}
Output :

100
Hello world This is malloc()

At above example the code segment :
if(ptr == NULL) {
  printf("!! Unable to allocate memory.\n");
  exit(1);
}
The above code snippet is used to check weather the space is allocated or not by using the pointer value returned by the memory allocation function, and if it is null then the memory is not allocated.

Example 2 :

In below example the integer pointer ptr stores 5 integer numbers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int *ptr, i;

  ptr = (int *)malloc(5 * sizeof(int)); // allocates 5*4 = 20 bytes
  if(ptr == NULL) {
    printf("!! Unable to allocate memory.\n");
    exit(1);
  }
  *(ptr) = 100;     // represents 0-4th bytes
  *(ptr+1) = 200;   // represents 4-8th bytes
  *(ptr+2) = 300;   // represents 8-12th bytes
  *(ptr+3) = 400;   // represents 12-16th bytes
  *(ptr+4) = 500;   // represents 16-20th bytes

  for(i=0;i<5;i++) {
    printf("%d\n", *(ptr+i));
  }

  return 0;
}
Output :

100
200
300
400
500

calloc() Function :

calloc() is another memory allocation function in C language which allocates multiple blocks of storage, each of the same size, and then sets all bytes to zero. The general form of calloc is :
 ptr = (cast-type *)calloc(n, element-size);
The above statement allocates contiguous space for n blocks, each of size 'element-size' bytes, and all bytes are initialized to zero and a pointer to the first byte of the allocated region is returned. If there is not enough space, a NULL pointer is returned. For example :
 ptr = (int *)calloc(5, sizeof(int));
The above statement allocates 5 integer block (total size 5*4 = 20 bytes) of memory space. We can write the Example 2 as :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int *ptr, i;

  ptr = (int *)calloc(5, sizeof(int));  // allocates 5*4 = 20 bytes
  if(ptr == NULL) {
    printf("!! Unable to allocate memory.\n");
    exit(1);
  }

  *(ptr) = 100;    
  *(ptr+1) = 200;
  *(ptr+2) = 300;
  *(ptr+3) = 400; 
  *(ptr+4) = 500;  

  for(i=0;i<5;i++) {
    printf("%d\n", *(ptr+i));
  }

  return 0;
}

realloc() Function :

If the previously allocated memory is insufficient or more memory space is required, then we can use the re-allocate or modify the existing size of memory by using realloc() function. This process is called the reallocation of memory. The syntax of  realloc() is as follows :
 ptr = (cast-type *)realloc(ptr, NewSize);
The above statement allocates a new memory space of size newsize to the pointer variable ptr and returns a pointer to the first byte of the new memory block. The newsize may be larger or smaller than the size.
 ptr = (int *)realloc(ptr, sizeof(int));
Also note that the new memory block may or may not begin at the same place as the old one. In case it is not able to find additional space in the same region, it will create the same in an entirely new region and move the contents of the old block into new block. The function guarantees that the old data will remain intact.

If the function is unsuccessful in locating additional space, it returns a NULL pointer and the original block of freed (or lost). This implies that it is necessary to test the success of operation before proceeding further.

C Example Code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  char *ptr;

  ptr = (char *)malloc(10);
  if(ptr == NULL) {
    printf("!! Unable to allocate memory.\n");
    exit(1);
  }

  strncpy(ptr, "HELLO", 10);
  printf("%s\n", ptr);

  // reallocating memory
  ptr = (char *)realloc(ptr, 30);
  if(ptr == NULL) {
    printf("!! Unable to allocate memory.\n");
    exit(1);
  }

  strncpy(ptr, "Hello world This is realloc()", 30);
  printf("%s\n", ptr);
  return 0;
}
Output :

HLLO
Hello world This is realloc()

Another example of realloc() :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int *ptr, i;

  ptr = (int *)malloc(sizeof(int));

  if(ptr == NULL) {
    printf("!! Unable to allocate memory.\n");
    exit(1);
  }

  *ptr = 100;
  printf("%d\n", *ptr);

  ptr = (int *)realloc(ptr, 5*sizeof(int));
  *(ptr+1) = 200;
  *(ptr+2) = 300;
  *(ptr+3) = 400;
  *(ptr+4) = 500;

  printf("After realloc()\n");
  for(i=1;i<5;i++) {
    printf("%d\n", *(ptr+i));
  }

  return 0;
}
Output :

100
After realloc()

200
300
400
500


free() Function :

The memory space allocated by malloc() or calloc() functions are must be released or freed by calling free() function.

When we no longer need the data we stored in a block of memory, and we do not intend to use that block for storing any other information, we may release that block of memory for future use. The syntax for free() function is :
 free(pointer);
Example C Code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
  int *ptr;
  
  ptr = (int *)malloc(sizeof(int));
  if(ptr == NULL) {
    printf("!! Unable to allocate memory.\n");
    exit(1);
  }

  *ptr = 100;
  printf("%d\n", *ptr);
  free(ptr);
  return 0;
}
Output :

100

Next Topic :