I'm trying to test the free function with this program
char **tab;
// allocation
tab = malloc(5 * sizeof(char*));
for(int j=0 ; j<5 ; j++)
{
tab[j] = malloc(4 * sizeof(char));
}
// FILL TAB FIRST WAY
/*
for(int j=0 ; j<5 ; j++)
{
for(int i=0 ; i<4 ; i++)
{
tab[j][i] = '@';
}
}
*/
// FILL TAB SECOND WAY
for(int j=0 ; j<5 ; j++)
{
tab[j] = "@@@@";
}
//free
for(int j=0 ; j<5 ; j++)
{
free(tab[j]);
}
free(tab);
The first way to fill the tab (each character individually) returns no memory errors with valgrind whereas the second way (filling the tab line by line) do returns some memory errors.
HEAP SUMMARY:
==447== in use at exit: 20 bytes in 5 blocks
==447== total heap usage: 6 allocs, 6 frees, 60 bytes allocated
==447==
==447== Searching for pointers to 5 not-freed blocks
==447== Checked 64,648 bytes
==447==
==447== LEAK SUMMARY:
==447== definitely lost: 20 bytes in 5 blocks
==447== indirectly lost: 0 bytes in 0 blocks
==447== possibly lost: 0 bytes in 0 blocks
==447== still reachable: 0 bytes in 0 blocks
==447== suppressed: 0 bytes in 0 blocks
==447== Rerun with --leak-check=full to see details of leaked memory
==447==
==447== ERROR SUMMARY: 5 errors from 1 contexts (suppressed: 0 from 0)
==447==
==447== 5 errors in context 1 of 1:
==447== Invalid free() / delete / delete[] / realloc()
==447== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==447== by 0x400607: main (test_malloc.c:35)
What is the explanation for that ?
For your second scenario, you've allocated memory using:
tab[j] = malloc(4 * sizeof(char));
Then overwritten the pointers with the address of "@@@@"
(a string literal):
tab[j] = "@@@@";
So you've just:
malloc
ed memory (what your LEAK SUMMARY
states).free()
a string literal (what your ERROR SUMMARY
states).If you want to properly copy "@@@@"
into the memory, you could use strncpy()
:
strncpy(tab[j], "@@@@", 4);