If you want to work with an array. You have to specify the size of the array at the time of declaration. Now, some users may work with a large number of data and some users may work with a very small number of data. So, as a developer, you should declare the array with such a size, which can be used by every user.
Here the problem is, that if the user works with a very small number of data, a huge volume of memory space is not in use. And using an array, memory is being allocated based on its size specified at the time of declaration. But if this memory can be allocated at run time, it will be beneficial.
Hence, using dynamic memory allocation, the chunk of memory can be allocated at run time.
In the C programming language, three functions (
malloc
, calloc
and realloc
) are used for dynamic memory allocation and one function (free
) is used for de-allocation.Please note that you have to include stdlib.h in order to use malloc or calloc or realloc or free
malloc | It takes one argument which should be an unsigned integer value dictating the function of how many bytes of storage to allocate. In general, this unsigned integer is placed as n*sizeof(datatype) format where n is the number of elements to be stored and sizeof (datatype) gives the memory requirement (in bytes) for the corresponding data type. Usage of sizeof ensures the correct memory requirement for a corresponding data type in changing operating systems, thereby maintaining the portability of the program. It does not initialize the newly allocated memory. Function malloc returns a void * or generic pointer to its caller. This void * will actually point to the first location of the allocated memory.
As the memory pointed by void * can store any data type, hence the programmer has to cast it as per the requirement of the code.
For example, if malloc is being used to allocate memory space to store some integers, hence the call to malloc has to be cast properly as int * instead of void * and the returned pointer must be caught back by an int * Let us consider that we want to store n (a dynamic value received from the user) number of integers in an array. The following code snippet will do it int *p; p = (int *) malloc (n * sizeof(int)); It is noteworthy, that the memory allocated by malloc has necessarily to be in a chunk and monolithic. |
calloc | Function calloc is also used to allocate memory dynamically. It takes two arguments, where the first argument should be an unsigned integer value dictating the function about the number of elements for which memory will be allocated and the second argument is the size of an element. Hence the argument of the calloc is placed as n, sizeof(datatype). The return type of calloc is the same void * as calloc and all the discussions related to the return type and its proper casting of malloc are equally true for calloc also. Function calloc initializes the newly allocated memory by default value. Function calloc differs a little from malloc while allocating the memory. First, it tries to allocate memory as a monolithic chunk as malloc, and if it fails to do so for the shortage of contiguous memory, then it allocates n number of smaller memories of size sizeof(datatype). So using calloc never guarantees allocated memory to be monolithic. Let us consider that we want to store the k (a dynamic value received from the user) number of floats in an array. The following code snippet will do it float *k; k = (float *) calloc (n , sizeof(float)); |
realloc | The realloc is a function that attempts to change the size of a previously allocated block of memory. The new size can be larger or smaller. If the block is made larger then the old contents remain unchanged and memory is added to the end of the block. If the size is made smaller then the remaining contents are unchanged. It takes two arguments as void * and new memory requirement as an unsigned integer. The first argument void * points to the base address of the memory previously allocated. There might be an interesting case while realloc tries to increase the memory and fails to find that much memory in place. In this situation, a whole new monolithic chunk of memory is discovered and the existing data is first copied and then the base address of the newly found monolithic memory is returned as void *. This returned void * must be properly cast as per the data type of existing elements. Even the trickier situation might so happen that realloc does not discover any monolithic chunk as per the memory requirement at all. In that case, realloc will fail and a NULL pointer would be returned. Hence realloc ensures that the allocated memory would always be in a chunk. |
free | If we want to de-allocate memory from a pointer uses the free function. It takes the void * as an argument and this void * actually points the memory to be de-allocated. |
Example using malloc
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, n, *ptr, sum = 0;
// take number of elements as input
printf("How many elements do you want to store?");
scanf("%d", &n);
ptr = (int *) malloc(n * sizeof(int));
// test default values of ptr
for(i = 0; i < n; i++)
printf(" %d ", ptr[i]);
// take the elements as input
printf("Enter the elements:");
for(i = 0; i < n; i++)
scanf("%d", &ptr[i]);
// calculate sum
for(i = 0; i < n; i++)
sum += ptr[i];
printf("\nSum is %d", sum);
return 0;
}
Example using calloc
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, n, *ptr, sum = 0;
// take number of elements as input
printf("How many elements do you want to store?");
scanf("%d", &n);
ptr = (int *) calloc(n, sizeof(int));
// test default values of ptr
for(i = 0; i < n; i++)
printf(" %d ", ptr[i]);
// take the elements as input
printf("Enter the elements:");
for(i = 0; i < n; i++)
scanf("%d", &ptr[i]);
// calculate sum
for(i = 0; i < n; i++)
sum += ptr[i];
printf("\nSum is %d", sum);
return 0;
}
Example using realloc
The following program illustrates how the
realloc
function is used to change memory allocation at run-time.In this program, first, a memory block is allocated for the variable
str
. Later we need to change the size of the memory block, thus we have to call the realloc
function to increase the size of the memory block. This function performs reallocation without affecting previous data.In this function, we are also using the free function to deallocate the memory which is pointed by variable str.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, n, *ptr, sum = 0;
// take number of elements as input
printf("How many elements do you want to store? ");
scanf("%d", &n);
ptr = (int *) calloc(n, sizeof(int));
// test default values of ptr
for(i = 0; i < n; i++)
printf(" %d ", ptr[i]);
printf("\n");
// take the elements as input
printf("Enter the elements:");
for(i = 0; i < n; i++)
scanf("%d", &ptr[i]);
// calculate sum
for(i = 0; i < n; i++)
sum += ptr[i];
printf("\nSum is %d", sum);
// take number of elements as input
printf("\nIf you want to store more elements? \nEnter number of elements you want to store. ");
scanf("%d", &n);
ptr = (int *) realloc (ptr, n);
// take the elements as input
printf("Enter additional elements:");
for(j = i; j < n; j++)
scanf("%d", &ptr[j]);
// calculate sum
for(j = i; j < n; j++)
sum += ptr[j];
printf("\nSum is %d", sum);
free(ptr);
return 0;
}
Dynamic memory allocation for 2D array.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, m, n;
int **arr;
int *row;
printf("Enter the order of matrix 1: ");
scanf("%d %d", &m, &n);
arr = (int **) malloc (m * sizeof(int *));
for(i = 0; i < m; i++)
{
row = (int *) malloc (n * sizeof(int));
arr[i] = row;
}
printf("Enter the values of matrix 1: \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
scanf("%d", &arr[i][j]);
}
}
printf("The given matrix is: \n");
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf(" %d", arr[i][j]);
}
printf("\n");
}
return 0;
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.