At the moment I am messing around a little bit with Sorting Algorithms in C. In the course of this I have run into the following problem: I have defined an int array with
int array[LENGTH];
where LENGTH is a globally defined variable. Then I am trying to change the first element of the array.
array[0] = 1;
When compiling with gcc and executing I am facing a segmentation fault. And after executing the binary file with valgrind I am given the following error:
Conditional jump or move depends on uninitialised value(s)
As I run valgrind again, now with the flag --track-origins=yes, valgrind leads me to the exact line where the initial array was defined.
Doing the same thing on the heap does not change anything:
int* array = (int*) malloc(LENGTH*sizeof(int));
*(array+0) = 1;
...
free(array)
However, I was always told that my OS does not distinguish between initialised and uninitialised variables and that it instead simply reads whatever garbage is stored at the allocated storage segment, no matter if the value at the address of the array (on the stack or heap) was set or not.
Now I am confused. How does my system recognise if a variable at a certain location is initialised? Or am I on the the completely wrong path and storage on the stack and heap is only allocated when initialising a variable (this would explain alot)?
Thanks for the help!
The OS does not know.
Valgrind however emulates the machine code (instructions) that are executed by your program and realizes that you are reading something from a memory address where you have never written anything before (and that does not belong to a program segment that is automatically initialized on program start), so it considers it as reading uninitialized data.
If, after detecting a read of uninitialized data, Valgrind encounters instructions that depend on such data, it will emit a warning such as the one you are seeing.