What a memory leak is and how do you avoid it?
In this instructional exercise, you will realize what is a memory break and what is the reasons for memory spills in C/C++ programming. You will likewise hole to how to stay away from memory spills in C/C++ with programming models.
What is Memory Leak?
A memory spill is a revile for programming since programming shows indistinct way of behaving because of the memory spill. The memory spill happens when developers neglect to deallocate the assigned memory.
Read Also: What Are Interview Questions For JavaScript?
We should see a program,
In the underneath program, the developer neglects to free the dispensed memory, it can cause a memory spill.
int main()
{
char * pBuffer = malloc(sizeof(char));
/* Do some work */
/*Not freeing the allocated memory*/
return 0;
}
What is implied by memory spills?
A memory spill resembles a sluggish toxic substance for accessible memory space. It is a steady loss of accessible memory when an application more than once neglects to return the distributed memory that it has gotten for impermanent use. Accordingly, the accessible memory for that application becomes depleted and the application can never again work.
So memory spill is a difficult issue for an application that runs ceaselessly (servers) in light of the fact that a tiny memory break can ultimately make the application end.
Some explanation of memory spill in C/C++:
For the most part, a memory spill happens in C/C++ programming when the pointer is lost its unique dispensed esteem. It turns into the reason for the memory spill in light of the fact that the allotted article becomes inaccessible and can’t be deallocated. We should see a few instances of memory spills.
- Assign the various qualities to the pointer prior to calling the erase articulation. See the referenced Model,
Example:-
// Dynamically allocated int with malloc()
int* ptr = (int*)malloc(sizeof int);
// Assign null to pointer before calling free function.
ptr = NULL; // memory leak
Example:-
// Dynamically allocated int with value 6
int* ptr = new int(6);
// Assign null to pointer befoer calling delete expression.
ptr = nullptr; // memory leak
An exemption happens prior to erasing the memory. Model,
void f()
{
//Dynamically allocated in with value 27
int* ptr = new int(27);
g(); // may throw
delete p; // okay if no exception
} // memory leak if g() throws exception
3. pointer leaves scope.
Example 1
void f()
{
//local pointer dead once control goes out of the scope.
// Allocated memory remain blocked when pointer dead.
int* p = malloc(sizeof int);
} // memory leak
Example 2
void f()
{
//local pointer dead once control goes out of the scope.
// Allocated memory remain blocked when pointer dead.
int* p = new int(7);
} // memory leak
How to keep away from memory spill in C?
There are many instruments accessible to distinguish memory spills. In any case, we can likewise keep away from the memory break to follow some programming tips. So let see the tips,
1. Each malloc or calloc ought to have a free capability:
It is a brilliant rule to compose the free capability after each malloc (calloc) capability. Assume in an application you have expected to make a variety of characters to store a few unique information. Since we realize that in C programming we utilize the memory the executives capability (malloc or calloc) to make a powerful exhibit.
It is a beneficial routine to compose the free capability soon after the malloc or calloc. It forestalls the situation when the engineer neglects to compose the free capability.
int fun(int n)
{
char *pInfoData = malloc (n *sizeof(char));
free(pInfoData);
return 0;
}
Presently begin to compose the code among malloc and free capability. Like the underneath articulation.
At times we have required dispensed memory all through the application, in that particular situation we need to compose the free capability in an overseer that will conjure toward the finish of the application. What’s more, we need to compose the free capability soon after composing the malloc capability to keep away from the opportunity to neglect.
For instance,
Assume there is a callback capability DeactivateHandler() that is summoned toward the finish of the application, so we need to compose the free capability in DeactivateHandler() soon after composing the malloc. These methods lessen the likelihood to neglect to free the memory.
2. Stay away from the stranding memory area:
At the hour of memory deallocation, we really want to liberate the memory from youngster to parent which implies a kid will be free first. In the event that we free the parent first, it tends to be a reason for memory spill.
For instance,
In the underneath code, the pointer to setting structure is liberating first. So the pointer that is highlighting space for the data information become vagrant and it tends to be a reason for memory spill.
typedef struct
{
void *pvDataInfo;
} sContext;
//Allocate the memory to pointer to context structure
sContext *pvHandle = malloc(sizeof(sContext));
//Allocate the memory for Information data
pvHandle-> pvDataInfo = malloc(SIZE_INFO_DATA);
free(pvHandle); // pvDataInfo orphan
3. Make a counter to screen distributed memory:
It is a decent strategy to forestall memory spills. In this procedure, we will make two worldwide counters and instate them with 0. In each effective portion, we will augment the worth of the counter1 (Allocate_Counter ) and in the wake of deallocating the memory we will augment the counter2 (Deallocate_Counter). Toward the finish of the application, the worth of the two counters ought to be equivalent.
This strategy assists you with following the situation with dispensed memory. To execute this method we want to make three redo capabilities, one for memory assignment, and second for memory deallocation, and the final remaining one to check the memory spill.
static unsigned int Allocate_Counter = 0;
static unsigned int Deallocate_Counter = 0;
void *Memory_Allocate (size_t size)
{
void *pvHandle = NULL;
pvHandle = malloc(size);
if (NULL != pvHandle)
{
++Allocate_Counter;
}
else
{
//Log error
}
return (pvHandle);
}
void Memory_Deallocate (void *pvHandle)
{
if(pvHandle != NULL)
{
free(pvHandle);
++Deallocate_Counter;
}
}
int Check_Memory_Leak(void)
{
int iRet = 0;
if (Allocate_Counter != Deallocate_Counter)
{
//Log error
iRet = Memory_Leak_Exception;
}
else
{
iRet = OK;
}
return iRet;
}