The memory leak happens when allocated memory is never used again and is not freed. This can happen in these two situations:
- The memory’s address is lost,
- The allocated memory is not freed when it should be (also called a hidden leak).
The memory leaks are problematic because the memory can’t be reclaimed and used later and this causes that the amount of memory available to the heap manager is decreased. This can leads to the program terminating if there is not enough available memory when calling malloc or in extreme case, the operating system may crash. If none of this happens, at minimum, memory is not being used efficiently.
Losing address
#include <stdlib.h>
int main(void)
{
int *ptr;
ptr = (int *)malloc(sizeof(int));
*ptr = 5;
ptr = (int *)malloc(sizeof(int));
free(ptr);
return (0);
}
Terminal> gcc MemoryLeaks.c
Terminal> valgrind ./a.out
==13560== Memcheck, a memory error detector
==13560== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13560== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==13560== Command: ./a.out
==13560==
==13560==
==13560== HEAP SUMMARY:
==13560== in use at exit: 4 bytes in 1 blocks
==13560== total heap usage: 2 allocs, 1 frees, 8 bytes allocated
==13560==
==13560== LEAK SUMMARY:
==13560== definitely lost: 4 bytes in 1 blocks
==13560== indirectly lost: 0 bytes in 0 blocks
==13560== possibly lost: 0 bytes in 0 blocks
==13560== still reachable: 0 bytes in 0 blocks
==13560== suppressed: 0 bytes in 0 blocks
==13560== Rerun with --leak-check=full to see details of leaked memory
==13560==
==13560== For lists of detected and suppressed errors, rerun with: -s
==13560== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
As seen in the example above, there are definitely lost 4 bytes in 1 block. The same happen if we use two time free. Below you can see graphical illustration.
Another example of losing the address can be following block of code:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
char *name;
name = (char *)malloc(sizeof("Toto" + 1));
strcpy(name, "Toto");
while (*name != '\0')
{
printf("%c", *name);
name++;
}
return (0);
}
What happens here that in the end the pointer name points to a NULL character (‘\0’) and the address of allocated memory was lost.
Hidden memory leaks
Hidden memory leak is when the program should release the memory but it does not happen. This is commonly a fault of coder’s oversight. As the result the object is kept in the heap when this object is no longer needed.
Memory leaks can also happen when we free structures that were created using the struct keyword. The point is that if the structure contains pointers to dynamically allocated memory, these pointers need to be freed before the structure is freed.
SOURCES:
[1] Understanding and Using C Pointers by Richard Reese (O’Reilly). Copyright 2013 Richard Reese, Ph.D. 978-1-449-34418-4