Pages

Tuesday, August 25, 2015

Dynamic Memory Allocation in C

Many programmers think that dynamic memory allocation is difficult to learn. I was one of them. However, after going through some tutorials I found it to be quite easy.

Why dynamic memory allocation ?

Allocating large data objects are compile time is not always practical if data objects are used infrequently and for a short time. So, these data objects are allocated at run time.

What is dynamic in dynamic memory allocation ?

It is called dynamic because the memory is allocated at run-time as opposed to compile time. One more important thing to note about dynamic memory allocation is that the memory is allocated in heap as opposed to stack.

How to implement dynamic memory allocation ?

C provides four different functions for dynamic memory allocation. They are:

1. malloc : The malloc() function returns a void pointer to the allocated memory or NULL if the
memory could not be allocated. You should always check the returned pointer for NULL. Please note that there is a big difference between void pointer and NULL pointer. Void pointer does not have type but it does have a valid pointer to an address. However, NULL pointer does not have any address.

Syntax :  data_type *p = (data_type *) malloc(size_t);
(data_type *) is the cast. malloc returns a void pointer. So, it is important to type cast to correct pointer type.

Eg : int *data;
        *data = (int*) malloc(sizeof(int));

  •  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.
  •  You should always free a block of memory that has been allocated by malloc() when you are finished with it. If you rely on the operating system to free the block when your program ends, there may be insufficient memory to satisfy additional requests for memory allocation during the rest of the program’s run.
  • Avoid allocating small blocks (that is, less than 25 or 50 bytes) of memory. There is always some overhead when malloc() allocates memory—16 or more bytes are allocated in addition to the requested memory.
  • Avoid allocating small blocks (that is, less than 25 or 50 bytes) of memory. There is always some overhead when malloc() allocates memory—16 or more bytes are allocated in addition to the requested memory.


2. calloc : The calloc library function assigns memory but with two major differences.
     a. Calloc takes two parameters, number of elements and size of element. The product of these                 elements determine the size of the memory block to allocate.
     b. It initializes the memory it allocates to zero.

      Syntax : data_type *p = (data_type *) calloc(n,size_t);
      Eg : int *data;
              *data = (int *) calloc(n, sizeof(int);

     There is a limit to the number of bytes that can be allocated by malloc or calloc function at one             time. That is 65,510 bytes in certain compiler.


3. free : This function returns allocated memory back to the operating system.The free() function is         almost foolproof. The pointer array is initialized to NULL which is a safe value because if someone tries to free the already freed pointer, there is no error. Errors could occur, however, when you 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 multi-threaded operating system,
  • Is not yours to free.
4. realloc : When we are not sure as to how much of memory is required for certain operation we can first assign a small amount of memory using calloc() or malloc() and then call realloc() to make the block larger.

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

The pointer ptr points to memory block previously allocated with malloc, calloc or realloc. If is is NULL a new block of memory is allocated and the pointer to that block is returned.

size is the new size for the memory block, in bytes. If it is 0 and ptr points to an existing block of memory, the memory block pointed by ptr is deallocated and a NULL pointer is returned.

memset: This library function does not allocate or deallocate memory but initializes a block of memory to any value passed as it's parameter.

Syntax :  void *memset(void *str, int c, size_t n)


Parameters
  • str -- This is a pointer to the block of memory to fill.
  • c -- This is the value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.
  • n -- This is the number of bytes to be set to the value.

No comments:

Post a Comment