-1

From what I understand, uninitialized array in C means garbage value at memory allocated for the array. But when i experiment with that. So, I tried this.

#include <stdio.h>
int main (){
    int j[10];
    for(int k = 0; k < 10;k++){
        printf("j[%d]:%d\n",k,j[k]);
    }
}

Here is the output:

j[0]:0
j[1]:0
j[2]:0
j[3]:0
j[4]:0
j[5]:0
j[6]:0
j[7]:0
j[8]:0
j[9]:0

I assume clang just fixed by putting default value into them. I'm using Apple clang version 12.0.5 (clang-1205.0.22.11) running on M1 MacBook Air. Now here is the confusing part:

#include <stdio.h>
int main (){
    int i =10;
    int j[i];
    for(int k = 0; k < 10;k++){
        printf("j[%d]:%d\n",k,j[k]);
    }
}

Here is what i have got: First run

j[0]:13172736
j[1]:1
j[2]:13172736
j[3]:1
j[4]:0
j[5]:0
j[6]:1865774432
j[7]:1
j[8]:48
j[9]:0

Second run

j[0]:72499200
j[1]:1
j[2]:72499200
j[3]:1
j[4]:0
j[5]:0
j[6]:1806906720
j[7]:1
j[8]:48
j[9]:0

Third run.

j[0]:8912896
j[1]:1
j[2]:8912896
j[3]:1
j[4]:0
j[5]:0
j[6]:1870689632
j[7]:1
j[8]:48
j[9]:0

Fourth:

j[0]:15417344
j[1]:1
j[2]:15417344
j[3]:1
j[4]:0
j[5]:0
j[6]:1863988576
j[7]:1
j[8]:48
j[9]:0

There seems to be some pattern here, and its pretty consistent, where does this comes from?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
  • 1
    IIRC in a debug mode build, some compilers initialize the variables with some special values to make it clear that they are uninitialized. – Uwe Keim Aug 19 '21 at 07:28
  • 2
    Undefined behaviour can produce all kind of results, including consistent patterns. **Just avoid it.** – the busybee Aug 19 '21 at 07:38
  • 3
    "Garbage" does not mean "random". It means "not useful", "rubbish", or "trash". It comes from a previous activity, and maybe *that* activity was consistent. – Weather Vane Aug 19 '21 at 07:38
  • "....uninitialized array in C means garbage value" well, it can also be a trap representation. – Support Ukraine Aug 19 '21 at 07:38
  • Undefind behaviour is undefined.... – Jabberwocky Aug 19 '21 at 07:52
  • When you have an uninitialized array you are just using a portion of memory that you "weren't using" so if the compiler does not assign an "undefined value" to the array you'll just find the information there was before in that section of memory. – Fausto Sánchez Hoya Aug 19 '21 at 08:16
  • @UweKeim, thanks, maybe that is the case, tried on a different platform and gcc compiler, different pattern appeared, nonetheless consistent during multiple runs. – tony_20khz Aug 19 '21 at 09:17
  • 1
    [This is the only reference I found](https://stackoverflow.com/questions/3748511/how-to-debug-uninitialized-variables-in-vc#comment3963041_3748541). To quote: "_Uninitialized variables are not set to zero; they are initialized to special fill patterns, `0xcc` and `0xcd` (depending on whether the memory was allocated on the stack or the debug heap)._". Update: Found also [this in-deep explanation](https://stackoverflow.com/a/370362/107625). – Uwe Keim Aug 19 '21 at 09:20
  • 1
    @UweKeim, thanks, the second read is informative. – tony_20khz Aug 19 '21 at 11:45

1 Answers1

1

Before main runs, startup code runs. When you build a C program, the linker includes special startup code for the C environment, and it sets the start address for the program to the beginning of this code. (The address for this code might be indicated with the symbol _start or start.) When the program loader finishes loading your program into memory, it starts the program running at that address.

That code may initialize the stack area and set up initial data for the printf family of routines, for the malloc routines, and other features of C or your particular operating system. In doing so, it uses some stack space. The data you see left behind is the result of that activity. When the startup code is done, it calls your main routine.

The varying numbers you see are because modern general-purpose operating systems use address space layout randomization to hinder attackers. The result is that address of certain things in your program, such as the start of code, static data, or the stack, vary from run to run.

You cannot rely on this data or patterns in it. In particular, when you enable optimization while compiling your program, the compiler may change where arrays are laid out in memory or it may omit loading of data from memory if it figures out it is not necessary to produce the results required by the C standard. Additionally, the patterns may change between versions of your C compiler and its associated libraries, include the startup code, as new versions of the compiler may arrange things in memory differently and new versions of the startup code may leave different data behind as they do their work.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312