Search code examples
cvalgrindfreedouble-quotessingle-quotes

C programming - difference between freeing a char ** filled with simple quotes and filled with double quotes - valgrind


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 ?


Solution

  • 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:

    1. Lost track of the malloced memory (what your LEAK SUMMARY states).
    2. Attempted to 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);