4

I want to know if an array of int elements is declared in C. Is there a pattern according to which only some values of the array are assigned to 0 while others store garbage values? Ex:

#include <stdio.h>

void main()
{
    int a[5];
    int i;
    for (i=0;i<=4;i++)
    {
        printf("%d\n",a[i]);
    }
}

After I compile and run the program I get this output,i.e.

0
0
4195344
0
2107770384

So zeroes are there in a[0], a[1] and a[3] while a[2] contains the same value each time compiled and run whereas a[4] value keeps on changing (including negative numbers). Why does this happen that only some fixed indices of an array are initialized to zero and does it have something related to past allocation of memory space?

Dennis Meng
  • 5,109
  • 14
  • 33
  • 36
  • 8
    `void main()` is a sure sign of a book or tutorial written by someone who doesn't know the C language very well. The correct definition is `int main(void)` (except perhaps on some embedded systems, but it's unlikely you're using such a system). Find a better source of information. – Keith Thompson Aug 09 '13 at 20:46
  • @KeithThompson An even better definition would be `int main(int argc, char** argv)`. – glglgl Aug 09 '13 at 20:51
  • 2
    @glglgl: That's "better" only if the program refers to its command-line arguments. Both `int main(void)` and `int main(int argc, char *argv[])` are specifically mentioned in the ISO C standard as permitted definitions. – Keith Thompson Aug 09 '13 at 20:52
  • I've never seen a compiler that requires main to be declared as `int main(void)`. `void` is automatically implied when a function has no argument. And `int` is only required when you need to return the exit code to the environment, otherwise it's completely redundant, and if you use that some compilers require the user to explicitly return a value which is rather troublesome – phuclv Aug 09 '13 at 23:13
  • 2
    @LưuVĩnhPhúc Troublesome? So `return 0;` hurts your b*tt or what? And no redundance here - a program invokes undefined behavior if the signature of `main()` is not `int (void)` or `int (int, char **)`. –  Aug 10 '13 at 15:10
  • 1
    @LưuVĩnhPhúc: I hope you're talking about C++ when you say `int main()` is the same as `int main(void)`. Otherwise, you're wrong. `int main()` in C is a function named "main" that returns an `int` and has **an unknown number of parameters of unspecified type**. And that has been considered an obsolescent feature according to the standard since at least C99. –  Aug 10 '13 at 16:08
  • @JaspalSingh, it's encouraged since your question has received some attention that you select an answer that best answers your question. This enables other people with the same problem to quickly navigate through StackOverflow and find the correct answer, rather than posting a duplicate post to yours. – Jacob Pollack Aug 14 '13 at 07:15

4 Answers4

8

This behaviour is undefined and it is merely a coincidence. When you declare an array on the stack and do not initialize it then the array will take on values from another (likely the previous) stack frame.

Aside: If you wanted to zero-fill an array declared on the stack (in constant time) then you can initialize it using the following initialization syntax:

int arr[ 5 ] = { 0 };

It will write the first element as 0 and zero-fill the rest of the elements. However, if you declared an uninitialized array globally then it will automatically be zero-filled.

Jacob Pollack
  • 3,703
  • 1
  • 17
  • 39
  • [`{ 0 }` is silly](http://stackoverflow.com/q/14797810/560648); you yourself point out that you're _explicitly_ value-initializing the first element then leaving the rest to be _implicitly_ zero-initialised. Why would you do that? – Lightness Races in Orbit Aug 09 '13 at 21:54
  • 3
    @LightnessRacesinOrbit, no it's very necessary... read my aside again. I added an extra "However" to separate the two points I am attempting to communicate. – Jacob Pollack Aug 09 '13 at 21:59
  • And, of course, rather than using malloc for a dynamic array use calloc. – Hot Licks Aug 09 '13 at 23:00
1

In C, when you declare your array that way it will not initialize the array. That's all garbage data. It's luck that there are zeros.

If you want to init the array to 0 use

memset(a,0,sizeof(a));

Scotty Bauer
  • 1,277
  • 9
  • 14
1

This is an undefined behavior and it depends on the OS. The initial value of unassigned arrays is undefined. As a matter of good practice it is your responsibilty to assign them a value.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • Technically speaking it's completely _defined_ that the values are _unspecified_. – Lightness Races in Orbit Aug 09 '13 at 21:54
  • 1
    @LightnessRacesinOrbit Array `a` is *indeterminate*. Reading from `a` is clearly *undefined behavior* in C90, arguably undefined behavior in C99+, and some C compilers treat it as undefined behavior. http://blog.frama-c.com/index.php?post/2013/03/13/indeterminate-undefined – Pascal Cuoq Aug 09 '13 at 22:21
  • @PascalCuoq: Oh, true, reading indeterminate values yields UB. I guess I was talking about the "values" themselves. Yes, I misspoke -- `s/unspecified/indeterminate/`. *thumbs up* – Lightness Races in Orbit Aug 09 '13 at 23:47
1

I just guess you run the code by terminal to say:

First, you run ./a.out or something else you named.

Second, then the termianl process (the parent process) call fork() to create a new process (the child process). now the child process is just looks the same as the parent process, everything is copyed from it's parent, like all data in stack memory.

Third, the child process called exce function to load you program.However, the new process didn't clear all not used memory, it just keep the value copyed from parent, even the part parent process did't initialize. So when you declare int a[5]; in child process without initialized, it just alloc a memeory sizeof 20 from stack ,OS know those memory belong to a[5], but the value in a[5], still the unknown. It can be every value, maybe that depand on the terminal process , maybe not.

So, It's a good custom to initialize the variables just when you declare it if you can.

just use int array = {0};

Lidong Guo
  • 2,817
  • 2
  • 19
  • 31