In dynamic allocation, a memory space of a certain size is reserved at runtime for exclusive use by the process that allocates it.
The C language has several complementary functions for dynamic memory management. The most commonly implemented are malloc(), realloc(), and free() which are part of the standard library and are defined in the “stdlib.h” header. These three functions allocate the memory to a process, change its size, and free it again.
In programming, it is very important to strictly manage the dynamic memory because every time we allocate the resources to a program, we take them away from the operating system. The mismanagement of dynamic memory can have catastrophic consequences for the processes that run in the system at that time.
In this Linux Hint article, you will learn how to use the free() function which is one of the three basic functions that the C language provides for dynamic memory management that frees the allocated resources and returns them to the operating system for reuse.
We’ll show you the syntax and the description of how it works, the input argument, and the data type that makes it up. Then, we will implement the use of the free() function in practical examples with code snippets and images which demonstrate its use and its effects on the system.
Syntax of the Free() Function in C Language
Description of the Free() Function in C Language
The free() function frees a specified amount of dynamically allocated memory.
The dynamic memory is allocated by calling the malloc() function and specifying the size in bytes of the area that you want to allocate in its input argument. As a result, this function returns the “Ptr” pointer which points to the newly allocated area.
The free() function frees the reserved memory space which is referenced by “Ptr” in its single input argument and returns its availability to the OS. This function returns no results and has no error definition in the “errno.h” header.
The free() function is part of the standard library and is defined in the “stdlib.h” header. To use it and the other dynamic memory management functions, you must include this header in your code as follows:
How to Free the Dynamically Allocated Memory Using the Free() Function
In this example, we create a very simple console application that gives us control over allocating the memory with the malloc() function and freeing the memory with the free() function. We then compile the code and run the application, monitor the system, and observe the effects.
To create the console application, we first include the required headers and open a main() function with an empty return. We declare the “Ptr” pointer in it which is used in the malloc() and free() functions for the pointers to the allocated memory areas. We also declare the integer size which determines the size of the allocated memory, and the integer option which is the condition for the switch that we use to select the menu option.
Once the required variables are declared, the application displays their PID using the printf() and getpid() functions. Then, the program enters an infinite loop where it displays a menu with two options. The user-selected item is retrieved using the scanf() function in the integer option and is the condition for a switch with two cases, one for each option.
The option 1 calls the malloc() function which allocates a 122 MB block of memory to the process. While the option 2 frees that block by calling the free() function. You can see the complete code of this application in the following illustration:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
void main()
{
int option;
char *Ptr;
int size=64000000;
printf("\nProcess ID: %i\n",getpid());
while (1){
printf ("\n[1] Allocate memory.\n[2] Release memory.\n");
scanf("%i", &option);
switch (option){
case 1:
printf("\nAllocating memory...\n");
Ptr=malloc(size*sizeof(char));
break;
case 2:
printf("\nReleasing memory...\n");
free(Ptr);
break;
}//End switch
}//End while (1)
}
Note that in case 1, the malloc() function allocates a memory area of size and returns the “Ptr” pointer. In case 2, the free() function uses the same pointer as input argument to free the allocated memory.
To see the effects of these two functions on the system, we need to open two command consoles. In terminal 1, we run the top command to see the resources that are used by each system process. In terminal 2, we compile and run the application that we just saw.
Once the application is running, we look at the console 1 for the resources that are used by the process whose PID is displayed in console 2.
As we can see in the figure, the system assigned PID number 13009 to the process. We can see in column 10 of the left terminal that our application consumes less than 0.1% of the system memory.
If we select the option 1 of our application and press “Enter”, the malloc() function allocates 122 MB of memory to the process.
As we can see in this image, the memory that is used by our application is now 3.6% of the total memory that is available in the system.
Now, we select option 2 of our application which calls the free() function, passing the “Ptr” pointer as an input argument. This action frees the memory that is allocated by the malloc() function in option 1.
In this image, we can see how the free() function freed the allocated memory from 3.6% to 0.1% of the total system that is used by our application.
Conclusion
In this Linux Hint article, we showed you how to use the free() function to free the dynamically allocated memory. We looked at the syntax of this function and the theoretical description of how it works.
Then, we applied what we learned in a practical example with code snippets and images where we created a console application that controls the calling of the malloc() and free() functions. We ran it step-by-step and monitored the system to see the effects of calling the functions to allocate and free the system memory.