0

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?

Soren
  • 14,402
  • 4
  • 41
  • 67
Adrien Horgnies
  • 691
  • 4
  • 11

3 Answers3

8

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.

MikeCAT
  • 73,922
  • 11
  • 45
  • 70
1

As far as I know only static variables will be set to NULL on initialisation. Other variables will point to a random memory locations with the value stored in that memory location. As a programmer using C/C++ you are responsible for the memory usage and what is stored in those locations (Memory Management is the term generally used). It does not do any of that work for you.

Careful Now
  • 260
  • 1
  • 9
1

Your variable (tabTestAllocate) is NOT initialized (See: Why aren't pointers initialized with NULL by default? ). This means that its value is undetermined. The pointer to it (&tabTestAllocate) clearly is defined. So in your if statement td_ptr has a defined (not NULL) value, while *td_ptr is undetermined. But this does not mean *td_ptr should be NULL, simply you do not know what it is, so you cannot know apriori if the condition will be true or not.

Community
  • 1
  • 1
Bruno Golosio
  • 113
  • 1
  • 7