In C programming language, when we want to create a program where the data is dynamic in nature, i.e. the number of data items keeps changing during the execution of the program, we can use dynamic data structures in conjunction with dynamic memory allocation methods to handle the program more easily and effectively.
- Dynamic memory allocation provides the flexibility of adding, deleting, or rearranging data items at run time.
- Dynamic memory allocation methods allow us to allocate additional memory space, or to release unwanted space at run time.
- Dynamic memory allocation function i.e. malloc(), calloc(), free(), and realloc are used in dynamic storage management.
- These functions are used in processing dynamic data structures like linked lists.
What is Dynamic Memory Allocation?
In Dynamic Memory Allocation, the memory space required by the variables in a program is calculated and assigned during the execution of the program. This helps in specifying the memory size required to avoid any wastage of memory due to specifying more memory than required or failure of the program due to specifying less memory than required.
- In doing so, we can write a flexible, easy, clean, and effective program that saves the computer’s memory while running the program flawlessly.
- Dynamic Memory Allocation methods are implemented using four library functions known as Memory Management Functions. These functions are used in allocating and freeing memory during the execution of the program.
- These four functions are used to build a complex application program that serves the need well and also uses the memory space intelligently.
What are the Memory Allocation Functions?
malloc() – It allocates the desired size of memory in bytes and returns a pointer to the first byte of the allocated space.
calloc() – It allocates the desired size of memory in bytes for an Array of elements, initializes them to zero, and returns a pointer to the allocated space.
free() – It frees previously allocated memory space.
realloc() – It modifies the size of previously allocated space.
Further, we will learn more about these functions, their syntax, and their use with few program examples for better understanding.
Process of Memory Allocation
Let us understand the process of memory allocation with an illustrated diagram given below.
We can assume the distribution of memory of a computer in a way like this:
Stack – It stores the local variables of the program.
Heap – This free memory region is used for dynamic memory allocation during the execution of the program.
Permanent storage region – It stores the program instructions and global and static variables of a program.
- There could be a possibility where the size of Heap keeps changing when the program is executed due to allocation, reallocation, and freeing of memory space used by the variables that are local to functions and blocks.
- So such a program can encounter a condition called Overflow during the dynamic memory allocation process.
- In such a situation, the memory allocation functions return a null pointer.
How to use Function malloc()?
Function malloc() is used to allocate a block of memory. It reserves a block of memory of a specific size and returns a pointer of type void. This allows us to assign it to any type of pointer.
General form of using Function malloc() is: ptr = (cast-type *) malloc(byte-size);
Example: x = (int *) malloc(10 *sizeof (int) );
- Here, x is a pointer of type int.
- The malloc() returns a pointer of type int to an area of memory with a size equivalent to “10 times the size of an int” bytes reserved.
- The address of the first byte of the memory allocated to the pointer x of type int.
Example: y = (char *) malloc(10);
Below is an illustrated diagram of the allocated space:
- Here, y is a pointer of type char.
- The malloc() returns a pointer of type char to an area of memory with size 10 bytes.
- Since the allocated memory space has no name, so it can only be accessed using a pointer.
- If there is not enough space in the Heap, a NULL Pointer is returned.
Below is an example to demonstrate the use of Function malloc().
Example: Program to print Array elements allotted at a memory space using Function malloc().
Code:
#include<stdio.h> #include<stdlib.h> int main() { int n; printf("Enter size of an Array: "); scanf("%d",&n); int *A = (int *) malloc(n * sizeof(int)); for (int i = 0; i < n; i++) { A[i] = i+1; } for (int i = 0; i < n; i++) { printf("%d ",A[i]); } return 0; }
Output:
Enter size of an Array: 5 1 2 3 4 5
How to use Function calloc()?
Function calloc() is used to request for memory space at run time for storing derived data types such as Arrays and Structures. It assigns multiple blocks of storage, each of the same size.
General form of using Function calloc() is: ptr = (cast-type *) calloc( n, unit-size );
- Here, function calloc() allocates contiguous space for n blocks, each of size unit-size.
- All bytes are initialized to zero and a pointer to the first byte of the allocated region is returned.
- If there is not enough space, a NULL Pointer is returned.
Below is an example to demonstrate the use of Function calloc().
Example: Program to print Array elements allotted at a memory space using Function calloc().
Code:
#include<stdio.h> #include<stdlib.h> int main() { int n; printf("Enter size of an Array: "); scanf("%d",&n); int *A = (int *) calloc(n, sizeof(int)); for (int i = 0; i < n; i++) { A[i] = i+1; } for (int i = 0; i < n; i++) { printf("%d ",A[i]); } return 0; }
Output:
Enter size of an Array: 10 1 2 3 4 5 6 7 8 9 10
How to use Function free()?
Function free() is used to release the used space when it is not required. It is very useful for situations when storage is limited. When we don’t need the data we stored in a block of memory, and we do not intend to use that memory block to store any other information, we may want to release or free that block of memory for future use, we can achieve this by using Function free().
General form of using Function free() is: free (ptr);
- Here, ptr is a pointer to a block of memory that has already been created using malloc or calloc.
- It is not the pointer that is being released but what it points to (original variable storing the value).
- In order to release an Array of memory that was allocated by calloc, we only have to release the pointer once.
- Individually releasing the Array elements will cause errors in the program.
Below is an example to demonstrate the use of Function free().
Example: Program to free the memory used in storing Array elements using Function free().
Code:
#include<stdio.h> #include<stdlib.h> int main() { int n; printf("Enter size of an Array: "); scanf("%d",&n); int *A = (int *) malloc(n * sizeof(int)); for (int i = 0; i < n; i++) { A[i] = i+1; } for (int i = 0; i < n; i++) { printf("%d ",A[i]); } free(A); return 0; }
Output:
Enter size of an Array: 8 1 2 3 4 5 6 7 8
How to use Function realloc()?
Function realloc() is used to alter the size of a block that has been already allocated by malloc or calloc. The need to alter the size of blocks arises if at a later time we want additional space for more elements or if we want to reduce the size of the block to avoid memory wastage. We can use Function realloc() to perform this task. And this process is called reallocation of memory.
General form of using Function realloc() is: ptr = realloc(ptr, newsize);
- Here, a new memory space newsize is allocated by the Function realloc() to the pointer ptr and returns a pointer to the first byte of the new memory block.
- The newsize may be larger or smaller than the previous size of the block.
- If the function is unable to locate additional space, it returns a NULL Pointer and the original block is freed (lost). So, it is safe to test the operation before proceeding further.
Below is an example to demonstrate the use of Function realloc().
Example: Program to print new Array elements by reallocating new memory space using Function realloc().
Code:
#include<stdio.h> #include<stdlib.h> int main() { int n,m; printf("Enter size of an Array: "); scanf("%d",&n); int *A = (int *) malloc(n * sizeof(int)); for (int i = 0; i < n; i++) { A[i] = i+1; } for (int i = 0; i < n; i++) { printf("%d ",A[i]); } printf("\n"); printf("Enter new size of an Array: "); scanf("%d",&m); A = realloc(A,20); for (int i = 0; i < m; i++) { A[i] = i+1; } for (int i = 0; i < m; i++) { printf("%d ",A[i]); } return 0; }
Output:
Enter size of an Array: 5 1 2 3 4 5 Enter new size of an Array: 10 1 2 3 4 5 6 7 8 9 10