Dynamic memory allocation in c

In c programming, we know the concept called an array. An array is a collection of similar data types having contiguous memory allocation.

The array has static memory allocation. i.e., the size of the array is fixed.

Eg. int array[8]={10,20,30,40,50,60,70,80};

        

malloc-c

                                                                  fig.1.

Fig 1. is an integer array memory block. It has a fixed size of 8. If we use only 4 blocks of memory, then the other 4 blocks will be wasted. We can not use more than 8 blocks of memory.

This is the disadvantage of an array. But, there is a solution to this problem. That is dynamic memory allocation.

If we want the size of the array according to our needs, at that moment, we can use dynamic memory allocation.

Dynamic memory allocation is a runtime process.

Using dynamic memory allocation, we can use memory as we want. Due to these program becomes flexible, and there is no wastage of memory.

 Dynamic memory allocation consist of four library function

  1.  malloc() 
  2.   calloc()
  3.   free() 
  4.   realloc()

this four library functions are defined under <stdlib.h> header file.

Let's see each one by one

1.  malloc() 
  Name malloc stands for memory allocation.
  It creates a block of memory with a reserved size. 
  It returns a pointer void that can be type_casted into a pointer of any data type.
Syntax::  void*malloc(size);

 ptr=(cast_type*)malloc(size);

cast_type: using cast_type, we can implicitly convert one data type into another, Here we are converting void into any other data type.

The size of allocated memory must be in bytes. 
 Initially, when the malloc function allocates the memory, it consists of garbage value under memory block.
  If the memory allocation fails, the function returns a null value.
  This function returns the void pointer that can be typecast to any other data type.
  The pointer points to the first block of allocated memory as it consists of the address of the first block of allocated memory.
  This pointer address is stored in the pointer variable “ptr”.
Example:: int *p;

                   p=(int*)malloc(5*sizeof(int));

 

dynamic-memory-allocation-c

Demo program

 
#include<stdio.h>
#include<stdlib.h>
int main()
{
 int *array,size,i;

 printf("Enter the size of array:\n");
 scanf("%d",&size);
 array=(int*)malloc(size*(sizeof(int)));
 if(array==NULL)
  {
   printf("Memory not allocated");
   exit(0);
  }
 printf("Enter the elements in an array:\n");
 for(i=0;i<size;i++)
 scanf("%d",&array[i]); 
 
for(i=0;i<size;i++)
 printf("%d. %d\n",i+1,array[i]);  
 
 
 free(); // used to dellocate the memory and free the space; 
return 0; 
 } 
 
output: 
Enter the size of array:
5
Enter the elements in an array:
10 20 30 40 50

1. 10
2. 20
3. 30
4. 40
5. 50
 


Let's discuss the above program,

  • Firstly we have taken the “size” as input that will decide the size of the array which we want. I have mentioned size as 5.
  • Now we have to allocate the memory for an array of size 5.

  array=(int*)malloc(size*sizeof(int)));

  array=(int*)malloc(size*2); // this is also valid syntax

 An array is an integer pointer that will hold the address of the first block of memory and point towards the array.

 We have type typecast the void pointer to int* as we are using int type of dynamic array.

  size*2= 5*2=10  10 bytes of memory will be allocated.

  • If(array==NULL) condition is given to check whether if memory is allocated or not. If it is not allocated, it will return a null value, and hence exit(0) is given so that the program will come out.                                                                                  
  • After allocating the memory, the input is taken at runtime.

 2.   calloc() 

Name "calloc" stands for contiguous memory.
As malloc creates only one block of memory, calloc create many blocks of memory continuously.
When the memory is allocated in calloc, by default it is initialized to zero.
Like malloc, it also returns a pointer. 
 Syntax:: void*calloc(n,size);
 ptr=(int*)calloc(n,size);
The syntax is similar to malloc,the only difference is malloc passes one argument and calloc  passes two arguments(number of elements and size of each element). 
If memory allocation fails, the function returns a null value.


calloc-function-c

     Example:: int *p;

               (int*)calloc(5,sizeof(int));


Demo program


#include<stdio.h>
#include<stdlib.h>
int main()
{
 int *array,n,i;
 
 printf("Enter the number of elements in the array:\n");
 scanf("%d",&n);
 array=(int*)calloc(n,(sizeof(int)));
  if(array==NULL)
  {
   printf("Memory not allocated");
   exit(0);
  }
 printf("Enter the elements in an array:\n");
 for(i=0;i<n;i++)
 scanf("%d",&array[i]); 
 for(i=0;i<n;i++)
 printf("%d. %d",i+1,array[i]); 
  free(); // used to deallocate the memory and free the space
return 0;
} 
 
output: Enter the size of array:5
Enter the elements in an array:
10 12 23 44 54
1. 10
2. 12
3. 23
4. 44
5. 54
 

3 .  free()

The  dynamically allocated memory using malloc() and calloc() does not get de-allocated. To de-allocate the memory and free the space, we use the free() function.

I have used free() in the demo program of malloc() and calloc() above.

4.  realloc()

after allocating the memory for malloc() or calloc(), if we feel that the memory which we have allocated is more or less at that point, we can use the realloc() function.

Name realloc stands for reallocation of memory.

We can reallocate the memory using realloc().

Syntax:: ptr=realloc(ptr,newsize);

ptr is reallocated with the new size.

          int *array; 

          array=(int*)malloc(6*sizeof(int)));

here dynamic memory has been allocated for 6 integers

 

realloc-c

We feel that the memory allocated is not sufficient, and we want to increase the size by 10.

array=(int*)realloc(array,16*sizeof(int)));

we reallocated the new memory of 16 size which is 6+10=16 size.

In bytes 6*2+10*2=32 

 now there are three cases in allocation.

1. 1. If enough 20 bytes of memory is presently followed by the previous 12 bytes, then the memory needed will be added in front of an old memory. In this case, the address of the pointer variable “array” will remain the same.

 
realloc-function-c

  This will not lead to any previous data loss. Old data is not lost, but newly allocated bytes are uninitialized.  

2. If enough 20 bytes of memory is not present, followed by the previous 12 bytes, then the whole 32 bytes of memory will be allocated at a new location. In this case, the address of the pointer variable “array” will be different.

dynamic-memory-allocation-c

 Old data is copied to new memory allocated, and new data is also filled after initialization.

3. In case if realloc() fails to reallocate the requested memory then, it will return a null value. Old data will remain unaffected.

 

 Demo program


 
 
#include<stdio.h>
#include<stdlib.h>
 int main()
 {
  int *array,size,size1,i;
   printf("Enter the size of an array:\n");
   scanf("%d",&size);
    array=(int*)malloc(size*(sizeof(int)));
     if(array==NULL)
       {
         printf("Memory not allocated");
         exit(0); 
       } 
 
 printf("Enter the elements in an array:\n");
  for(i=0;i<size;i++)
  scanf("%d",&array[i]);
 
size1=size+4;
printf("\n size1=%d",size1);
 
array=(int*)realloc(array,size*(sizeof(int)));
 
printf("\n Enter the elements in an extended array:");
 for(i=size;i<size1;i++)
 scanf("%d ", &array[i]);
 
printf("\n print all the elements in array:");
for(i=0;i<size1;i++)
  printf("%d ", array[i]);
 
 free(); // used to dellocate the memory and free the space
return 0;
} 
 

Output:

Enter the size of an array:

5

Enter the elements in an array:

20 32 45 54 64

size1=9

Enter the elements in an extended array:

50 60 70 80

print all the elements in array:

20 30 45 54 64 50 60 70 80