Dynamic Memory Allocation in C

malloc() function

  The malloc() library function allocates a block of memory according to the specified size. 

Rules to be followed to use malloc(),


  1. The malloc() function returns a pointer to the allocated area in memory or NULL if the memory could not be allocated. Hence we should always check the returned pointer for NULL.
  2. The pointer returned by malloc() should be saved in a static variable, unless you are sure that the memory block will be freed before the pointer variable is discarded at the end of the block or the function
  3. After utilizing the memory allocated by malloc(), the block of memory must be deallocated. If we depend on OS to free the block of memory when program ends, there may be insufficient memory to satisfy the additional requests for memory by other parts of your program.
  4. Try to avoid allocating small block of memory say less than 50 bytes. Because when we use malloc(), some additional bytes of memory is allocated (i.e. 16 bytes or more than 16) apart from requested memory.


The malloc() function requires only one argument i.e. the size of the block of memory to allocate. The size on many system is a short int. When you use the malloc() function, remember that the block of allocated memory is not initialized. If you want initialized memory, use memset() after the memory is allocated or use 




Example: 

int *x;
x = (int*)malloc(10 * sizeof(int));    //memory space allocated to variable x
free(x); // releases the memory allocated using malloc()

calloc() function

void *calloc( type num, type size ); 


malloc() allocates the memory but does not initilize the memory but calloc() allocates as well as initializes it. The calloc() library function allocates memory in the same way how the malloc()  function allocates, but with two differences. calloc() needs two arguments, not one: the number of elements and the size of each element. The product of these parameters determines the size of the memory block to allocate, and must fit in type type specified, which on many systems is a short int (16 bits).  The second difference is that the calloc() function initializes the memory it allocates to zero. The value used to initialize the memory is an absolute zero, which usually—but not always—evaluates to a floating-point zero or a NULL pointer value. This is fine if the memory will be used for string storage or integers. If the memory will be used for floating-point values, you should explicitly initialize the block of memory after calloc() returns. 

Example:

struct Item
{
 char *name;
 int price;
};

typedef struct Item P;

P *e1;

e1 = (P*) calloc(30,sizeof(P));


free() function
---------------------
void free( void *mblock ); 


free() function deallocates the memory allocated dynamically using malloc() and calloc(). Its function is to return the memory allocated by you to the OS. Memory is usually a limited resource even when you are running a system virtual memory- so we must give memory back when you are finished with it. Errors may occour when we try to free memory that, 


  • Was not allocated with one of the memory allocation functions;
  • Has been released through a prior call to free() or a call to         realloc();
  • Is currently in use by another thread in a multithreaded operating system
  • Is not yours to free.



       When free() is called, be sure you are passing a valid pointer to it . To make sure that the pointer is valid, check that it contains NULL or points to a properly allocated block of memory. Note that free() considers a NULL pointer to be always valid, and treats call with a NULL pointer as a no-operation, which means free() simply returns without freeing any memory.

realloc() function:

Syntax :


void *realloc( void *mblock,type size );


      We can use calloc() and allocate all available free memory for the structures. This might work, but it wastes a lot of memory. Another method is to call calloc() and allocate a small block, but the program would have to be stopped temporarily to save the data, this unnecessary create trouble. Or you could call calloc(), allocate a small block, call calloc() again when the block was filled and get a bigger block of memory, copy the small block of memory to the larger one, then free the small block. To do this more effort is required. The best solution is to call calloc() to allocate the initial array, then call realloc() to make the block larger. The realloc() function copies the contents of the original block of memory to the new block, then frees the original block, so your work is reduced.

Example :

int * ptr1 = (int*) malloc(5 * sizeof(int));
int * ptr2 = ptr1;

ptr2 = (int*) realloc(ptr2, 10 * sizeof(int));

Comments