Search code examples
cvalgrindfreecalloc

why are my variables not initialized?


I have reduced my code to the simplest to isolate my problem, I figured out what was my problem but I can't solve it. In fact, I don't even know if there is a problem.

I've got a function which is meant to initialize uninitialized variable and re initialize already initialized variables. My problem is that the variables I declare seems to be initialized.

Here is what is left of the code :

/**
  * This software defines the type TabDyn and gives the tools to manipulate it
  * 
  * TabDyn is conceptually an array of integers. The first element is the size while the others are the members of the array.
  *
  * Here are the function provided to manipulate TabDyn :
  *     td_clear(TabDyn* td) : Create the TabDyn object if non existant and initialize it to an empty one. If it exists, it empties it.
  *
  */

#include <stdio.h>
#include <stdlib.h>

// TabDyn[0] := size
// tabDyn[i] := i^th element of the array, first index being 1 (i>1)
typedef int* TabDyn;

/**
  * param - TabDyn* td_ptr : address of a declared int
  * void : initialize {td_ptr} to an empty array (size=0, no member)
  */
void td_clear(TabDyn* td_ptr)
{
    //this is the size of each member of TabDyn and thus the size of an empty TabDyn
    size_t TabDynByteCount = sizeof(int); 

    //We must free initialized TabDyn variables
    if(td_ptr && *td_ptr) 
    {
        printf("INITIALIZED!\n"); //#TOREMOVE#
        free(*td_ptr);  
    }

    //Create TabDyn object of size = 0 and give it to param
    *td_ptr = calloc(1, TabDynByteCount);
}

/**
  * Contains various test of the TabDyn function to ensure a correct behaviour by testing it at runtime with Valgrind
  */
int main()
{
    //* TEST decl-init-free #VALID:v0.04#
    printf("\n--- TEST OF td_clear BATCH 1 ---\n");
    printf("Declaring TabDyn variable\n");
    TabDyn tabTestAllocate;
    printf("Initialising TabDyn variable\n");
    td_clear(&tabTestAllocate);
    printf("Freeing now useless variables\n");
    free(tabTestAllocate);
    //*/
    //* TEST decl-init-init-free
    printf("\n--- TEST OF td_clear BATCH 2 ---\n");
    printf("Declaring TabDyn variable\n");
    TabDyn tabTestAllocate2;
    printf("Initialising TabDyn variable\n");
    td_clear(&tabTestAllocate2);
    printf("Re-initialising TabDyn variable\n");
    td_clear(&tabTestAllocate2); // It is not a duplicate
    printf("Freeing now useless variables\n");
    free(tabTestAllocate2);
    //*/
}

And here is what Valgrind says about it :

--- TEST OF td_clear BATCH 1 ---
Declaring TabDyn variable
Initialising TabDyn variable
==10875== Conditional jump or move depends on uninitialised value(s)
==10875==    at 0x400654: td_clear (in /home/adrien/Documents/c/examen)
==10875==    by 0x4006CD: main (in /home/adrien/Documents/c/examen)
==10875== 
INITIALIZED!
==10875== Conditional jump or move depends on uninitialised value(s)
==10875==    at 0x4C2CDE1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10875==    by 0x40066E: td_clear (in /home/adrien/Documents/c/examen)
==10875==    by 0x4006CD: main (in /home/adrien/Documents/c/examen)
==10875== 
==10875== Invalid free() / delete / delete[] / realloc()
==10875==    at 0x4C2CE2B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10875==    by 0x40066E: td_clear (in /home/adrien/Documents/c/examen)
==10875==    by 0x4006CD: main (in /home/adrien/Documents/c/examen)
==10875==  Address 0x400540 is in the Text segment of /home/adrien/Documents/c/examen
==10875==    at 0x400540: _start (in /home/adrien/Documents/c/examen)
==10875== 
Freeing now useless variables

--- TEST OF td_clear BATCH 2 ---
Declaring TabDyn variable
Initialising TabDyn variable
==10875== Conditional jump or move depends on uninitialised value(s)
==10875==    at 0x400654: td_clear (in /home/adrien/Documents/c/examen)
==10875==    by 0x40070D: main (in /home/adrien/Documents/c/examen)
==10875== 
INITIALIZED!
==10875== Conditional jump or move depends on uninitialised value(s)
==10875==    at 0x4C2CDE1: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10875==    by 0x40066E: td_clear (in /home/adrien/Documents/c/examen)
==10875==    by 0x40070D: main (in /home/adrien/Documents/c/examen)
==10875== 
==10875== Invalid free() / delete / delete[] / realloc()
==10875==    at 0x4C2CE2B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==10875==    by 0x40066E: td_clear (in /home/adrien/Documents/c/examen)
==10875==    by 0x40070D: main (in /home/adrien/Documents/c/examen)
==10875==  Address 0xffefffe70 is on thread 1's stack
==10875== 
Re-initialising TabDyn variable
INITIALIZED!
Freeing now useless variables
==10875== 
==10875== HEAP SUMMARY:
==10875==     in use at exit: 0 bytes in 0 blocks
==10875==   total heap usage: 3 allocs, 5 frees, 12 bytes allocated
==10875== 
==10875== All heap blocks were freed -- no leaks are possible
==10875== 
==10875== For counts of detected and suppressed errors, rerun with: -v
==10875== Use --track-origins=yes to see where uninitialised values come from
==10875== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)

but if I explicitly initialize my variables to NULL, there isn't any problem anymore :

 TabDyn tabTestAllocate = NULL;
 TabDyn tabTestAllocate2 = NULL;

Aren't my variables supposed to be initialize to NULL? Or is my if statement not testing what I think it tests?


Solution

  • No, they aren't supporsed to be initialized to NULL and they will have indeterminate values because they have automatic storage duration and aren't initialized explicitly.

    N1256 6.7.8 Initialization

    10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.