Monday, 24 November 2014

Memory Management functions malloc(), calloc(), and realloc() with examples

Memory Management functions malloc(), calloc(), and realloc():

The compiler allocates memory for the local variables on the stack. And there is a possibility that we can allocate memory on the heap using the memory allocation fucntions
malloc, calloc & realloc

Stack memory allocation:

The stack memory is allocated when the local variable found by the compiler and freed when the variable goes out of the scope
void myFun () {
int i; // memory is allocated on the stack
}

The memory is de-allocated when the scope of the variable goes out of scope.
The address is allocated statically for the local variables and the function arguments.

Heap memory allocation:
The heap memory allocated when we allocate the memory using malloc / calloc/ realloc and freed when we call the function “free”.malloc is a function that finds a chunk of free memory of the desired size and returns a pointer to it. free marks the memory associated with a specific address as no longer in use.
void myFun () {
  char pcch = (char*) malloc (sizzeof (char));   // memory allocation
// your statements
free (pcch);  // meory deallocation
}

How malloc and free functions works?
The malloc() function takes the integer as an argument argument to specify the bytes of memory to be allocated and void* as a return value. So we need to type cast it as per our requirement.The free() function accepts a pointer to the space for its argument.

Let us see the worked example to understand the malloc and free fucntions:
using namespace std;
#include <stdio.h>
#include <stdlib.h>
int _tmain (int argc, _TCHAR* argv[])
{
 int iMaxVal = 10;
 char *pcchVal = NULL;
 pcchVal = (char*)malloc( (iMaxVal + 1) *  sizeof(char));
 if(pcchVal != NULL)
  {
  for(int iIndx = 0; iIndx < iMaxVal; iIndx++)
   pcchVal[iIndx] = 'k'+ iIndx;
  pcchVal[iMaxVal] = '\0';
  printf ("pcchVal=%s\n", pcchVal);  
  free (pcchVal);
  return 0;
 }
 else {
  printf("Not enough memory\n");
  return 1;
 }
}
The output of the above program is
pcchVal=klmnopqrst

If the memory is not allocated using the function malloc, it returns NULL.

calloc function :

calloc allocates the requested memory and returns a pointer to it. calloc initializes allocated memory to zero., but using malloc it is not possible to set the allocated memory to zero.
The calloc() takes two integer arguments. These are multiplied together to specify how much memory to allocate.

Syntax of the calloc function:
void *calloc(size_t nitems, size_t size)

Here the parameters
nitems -- This is the count of elements to be allocated.
size -- This is the size of elements.
This function returns a pointer to the allocated memory, or it returns NULL if the request fails.

calloc function with example:
using namespace std;
#include <stdio.h>
#include <stdlib.h>
int _tmain (int argc, _TCHAR* argv[])
{
   int iIndex, iCount = 0;
   int *iVal = NULL;
   printf("Please enter Number of elements do u want");
   cin >> iCount;
   iVal = (int*)calloc(iCount, sizeof(int));
   cout << "you have Entered" << iCount << "numbers" <<endl;
   for(iIndex=0 ; iIndex <iCount ; iIndex++ )
   {
      cin >> iVal[iIndex];
   }
   cout <<"The total numbers you entered are:";
   for(iIndex=0 ; iIndex < iCount; iIndex++ ) {
      cout << iVal[iIndex] << endl;
   }
   getchar ();
   return(0);
}

Output is;
Please enter Number of elements do u want 4
you have Entered 4 numbers
2
3
4
5
The total numbers you entered are:
2
3
4
5

What is the difference between the malloc & calloc?
As discussed earlier calloc allocates the requested memory and returns a pointer to it. calloc initializes allocated memory to zero., but using malloc it is not possible to set the allocated memory to zero.

realloc function:
the memory allocated by malloc / calloc can be resized using reallco function.

The below are the few points that we need to understand about the realloc function.
The contents of the object will remain unaltered up to the lesser of the new and old sizes.
If the new size of the memory object would require movement of the object, the space for the previous instantiation of the object is freed.
If the new size is larger, the contents of the newly allocated portion of the object are unspecified.
If size is zero and ptr isn't a null pointer, the object pointed to is freed.
If the space can't be allocated, the object remains unaltered.
If ptr is a null pointer, realloc() acts like malloc() for the specified size.

Syntax of the realloc:
void * realloc (void * ptr, size_t size)

Return value:
 realloc() returns a pointer to the new space, or NULL if the request cannot be satisfied.

Example for realloc:
using namespace std;
#include <stdio.h>
#include <stdlib.h>
int _tmain (int argc, _TCHAR* argv[])
{
 char *pcchStr = NULL;
   /* Initial memory allocation */
   pcchStr = (char *) malloc(45);
   strcpy (pcchStr, "Examplerealloc");
   cout << "pcchString = " << pcchStr  <<  "Address = "<<pcchStr <<endl;
   /* Reallocating memory */
   pcchStr = (char *) realloc(pcchStr, 50);
   strcat (pcchStr, "firstprogram");
  cout <<"pcchString =" << pcchStr << << "\n" << Address" <<  pcchStr <<endl;
   free(pcchStr);
  getchar ();
 return 0;
}

Output is as shown below:
pcchString = Examplerealloc Address = Examplerealloc
pcchString =Examplerealloc firstprogram 
Address Examplerealloc firstprogram

free function:
The free function is used to free the previously allocated memory using malloc / calloc/realloc, it takes the pointer to a heap block and returns it to the free pool for later reuse

syntax of the free is
void free(void*)

Points we need to remember about the free is:
call to free() does not need to give the size of the heap block - the heap manager will have noted the size in its private data structures.
The call to free() just needs to identify which block to deallocate by its pointer. If a program correctly deallocates all of the memory it allocates, then every call to malloc() will later be matched by exactly one call to free().

No comments: