Menu Close

Dynamic Memory Allocation in C

  • Application is used to store and process the information.
  • We store information into memory.
  • In C, it is allowed to allocate the memory in 2 ways.
    • Static memory
    • Dynamic memory
  • Memory will be allocated to variables at runtime only
  • Compiler only converts the source code into binary code
  • Static memory is nothing but fixed size but allocates at runtime only
  • Dynamic memory varies depends on application requirement
  • Primitive variables always get static memory.
  • The memory size of variable will fix as soon as the program execution starts.
  • DMA is applicable only to Aggregate data types (arrays) and user-defined data types (structures).
  • We use DMA, only when we don’t know about how much memory has to be allocated for a variable at compile time.
  • stdlib.h library contains pre-defined functions to allocate and de-allocate the memory at runtime.
    • Malloc: allocates memory to structure variables
    • Calloc: allocates memory to array variables
    • Realloc: used to re-acquire the space
    • Free: used to release the memory
  • DMA refers allocating block of memory from available space and stores the reference into a pointer variable. Hence we can work with that block throughout the program using that pointer variable.

malloc() : Allocate memory to structures.

  • Prototype: void* malloc(size_t size);
  • “size_t” represents “unsigned” value.
  • malloc() function allocates number of bytes specified by the “size”.
  • On success, it returns base address of allocated block.
  • On failure, it returns NULL.
#include<stdio.h>
#include<stdlib.h>
struct emp
{
	int eno;
	char ename[20];
	float esal;
};
void main()
{
	struct emp *ptr;
	ptr = (struct emp*)malloc(sizeof(struct emp));
	if(ptr==NULL)
	{ 
		printf("out of memory\n");
		exit(1);
	}
	printf("Enter emp details\n");
	scanf("%d%s%f",&ptr->eno, ptr->ename, &ptr->esal);

	printf("Emp details\n");
	scanf("%d\n%s\n%f\n",ptr->eno, ptr->ename, ptr->esal);
}

calloc() :

  • void* calloc(size_t n , size_t size);
  • It is used to allocate the memory for array variables through pointers.
  • First argument specifies number of elements in the array.
  • Second argument specifies size of each element.
  • If memory is available, it allocate n*size bytes and returns first byte address.
  • If no memory, it returns NULL.
  • After allocating the memory all the byte locations are initialized with “0” by default.
#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* arr;
	int i, n;
	
	printf("Enter initial size : ");
	scanf("%d", &n);
		
	arr = (int*)calloc(n, sizeof(int));
	if(arr==NULL)
	{
		printf("Out of memory error\n");
	}
	else
	{
		printf("Elements are :\n");
		for(i=0 ; i<n ; i++)
		{
			printf("%d\n", *(arr+i));
		}
	}
	return 0;
}

Read elements into array and find the sum of array elements:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	int* arr;
	int i, n, sum=0;
	
	printf("Enter initial size : ");
	scanf("%d", &n);
		
	arr = (int*)calloc(n, sizeof(int));
	if(arr==NULL)
	{
		printf("Out of memory error\n");
	}
	else
	{
		printf("Enter elements :\n");
		for(i=0 ; i<n ; i++)
		{
			scanf("%d", arr+i);
		}
		
		for(i=0 ; i<n ; i++)
		{
			sum = sum + *(arr+i);
		}
		printf("Sum : %d \n", sum);
	}
	return 0;
}

realloc :

  • void* realloc(void* ptr, size_t size);
  • Using malloc function, we allocate memory for structure variables.
  • Mostly data structure algorithms implementation like linked lists, trees and graphs uses structure data type to create nodes.
  • for example in a double linked list, node structure will be…
struct node
{
	int data ;
	struct node* left;
	struct node* right;
};
  • In case of structure data type, we allocate the block of memory if required and deletes the block if not required.
  • But in case of arrays, once if we allocate the memory using calloc() function, that will be the fixed memory to store and process the elements
  • We can’t increase and decrease the size of the memory block.
  • realloc( ) functions is used to increase or decrease the size of memory block.
  • realloc( ) is mostly used to modify the size of array which has created dynamically.
  • first argument specifies the address of memory block from which it has to re-acquire the space
  • Second argument specifies new size of block.
  • On success, returns first byte address.
  • On failure, returns NULL pointer.
#include<stdlib.h>
void main()
{
	int *p1,*p2, m, n;
	printf("enter size of array : ");
	scanf("%d",&m);

	p1 = (int*)calloc(m,sizeof(int));
	if(p1 == NULL)
	{
		printf("calloc failed\n");
		exit(1);
	}
	else
	{
		printf("memory allocated..\n");
	}

	printf("Enter new size of array : ");
	scanf("%d",&n);
	
	p2=(int*)realloc(p1 , n*sizeof(int));
	if(p2 == NULL)
	{
		printf("realloc failed\n");
		exit(1);
	}
	else
	{
		printf("memory re-aquired..\n");
	}
	free(p1);
	free(p2);
}

Analyze the code:

#include<stdio.h>
#include<stdlib.h>
void modify();
int *arr, n, i=0;
void main()
{
	int count=0;
 	printf("Enter initial size : ");
  	scanf("%d", &n);
     
 	arr= (int*)calloc(n, sizeof(int));
  	while(1)
   	{
 		printf("\nEnter element :");
        if(n==count)
        {
        	modify();
        }
	scanf("%d", arr+i);
	 printf("Element inserted \n");
   	++i;
     	count++;
         
	printf("Do you want to continue(y/n) : ");
        if(getche()=='n')
        	break;
     }
 }
void modify()
{
      ++n;
      arr=(int*)realloc(arr, n*sizeof(int));
}

free() :

  • The memory which has allocated dynamically must be released explicitly using free function.
  • void free(void* ptr);
  • Using free() funtion , we can de-allocate the memory of any type of pointer.