2

Here is an Array program.

Practice.c

#include <stdio.h>

void main()
{
  int i,num[10]={10,20,30,40,50};

  for(i=0;i<15;i++)
  {
    printf("\nnum[%d] =%d",i,num[i]);
  }
}

Following is the output of the Program.

num[0] =10
num[1] =20
num[2] =30
num[3] =40
num[4] =50
num[5] =0
num[6] =0
num[7] =0
num[8] =0
num[9] =0
num[10] =10
num[11] =0
num[12] =2686711
num[13] =2686820
num[14] =4199443


Now I have 2 questions:

1- Why is num[5] to num[9] displayed there values as 0?

2- Why num[10] to num[14] are displaying these values, when I only have declared the length as int num [10] and not as int num [15], shouldn't the program be displaying an error while running or compiling?

phougatv
  • 881
  • 2
  • 12
  • 29
  • 2
    Bounds-checking isn't a feature built into C, or guaranteed by C. Why do you expect it? – Charles Duffy Jun 26 '14 at 01:37
  • Did u deleted your answer right now @Charles Duffy – phougatv Jun 26 '14 at 01:38
  • 1
    See e.g. [here](http://stackoverflow.com/questions/24335526/strange-values-being-initialized-into-array/24335623). Or one of the many questions here or elsewhere in the web about array initialization and out-of-bounds access. – mafso Jun 26 '14 at 01:39
  • I am using gcc, and every time I tried to check that whether it was my luck or not, the result was same. Uninitialized but declared arrays were showing there values as `0`. – phougatv Jun 26 '14 at 01:40

1 Answers1

4

Here is what your program is doing:

int num[10] = {10,20,30,40,50}

The above line tells the compiler to create an array of ten integers and initialize the first five values (indices 0-4) to the ones you provided. The remainder of the values (indices 5-9) are automatically initialized to zero per the C99 specification.

num[9] # This value was specifically allocated and initialized.
num[10] # This value was neither allocated nor initialized but it exists anyway.

When you say num[9] you are telling the compiler to access the integer that is nine integers away from the start of the array called num, in fact, it's almost exactly the same as saying *(num+(int*)9).

It's pure luck that you can access the 10th through 15th values - you didn't ask the compiler to allocate that space but it's there anyway, and the computer doesn't prevent you from looking at it.

In summary, you have just discovered the fact that the C language doesn't prevent you from accessing values that you have not initialized or specifically asked to allocate!

maerics
  • 151,642
  • 46
  • 269
  • 291
  • 2
    C99/C11 p.6.7.9 (19) and (21). The remaining fields are initialized to zero. – mafso Jun 26 '14 at 01:45
  • @maerics But if my `Ques-2` is luck than atleast 1 out of 20 times it must display an error. But, there is no error. Every single time, `Ques-1` displays `0`, and `Ques-2` garbage values, if they are garbage values. – phougatv Jun 26 '14 at 01:49
  • 2
    @VSP: the reason it never displays an error is because the compiler is always allowing you to access some large number of integers beyond the values you specifically allocated. Try changing `i<15` to `i<1000000` and see how far it will let you read! – maerics Jun 26 '14 at 01:51
  • @mafso: yes, that's true, but note that not all C compilers adhere to C99 by default, some still use C89. – maerics Jun 26 '14 at 01:54
  • 2
    _It's pure luck_ should be _it's pure undefined behaviour and you are looking for troubles_ – user2485710 Jun 26 '14 at 01:56
  • @maerics I tried `i<1000000` and the program stopped working at `num[4178] =0`. – phougatv Jun 26 '14 at 01:57
  • 1
    @VSP: as another user pointed out, this behavior is technically "undefined", meaning that the C language specification doesn't mandate specific rules for the compiler to adhere to, so it is free to make up its own. – maerics Jun 26 '14 at 02:00
  • @user2485710: yes, luck and trouble often hang out together. – maerics Jun 26 '14 at 02:01
  • That means it's not the normal behavior of the compiler. Compiler successfully compiled and executed my code due to some undefined behavior but extending the value to `i<1000000` in the for loop it showed the correct thing, isn't it? – phougatv Jun 26 '14 at 02:02
  • 1
    @VSP: it's a bit more complicated than that. The C language doesn't prevent you from trying to look at memory that you didn't ask it to allocate; the compiler just happened to create some extra values that you are allowed to access, and the compiler/OS are not obligated to prevent you from doing undefined things. – maerics Jun 26 '14 at 02:07
  • @maerics I tried that idea of urs `i<100000` with `Ques-1` and the compiler has successfully compiled and have executed the code without any problem – phougatv Jun 26 '14 at 02:07
  • @maerics I did `int num[100000]={10,20,30,40,50}` and also did `for(;i<100000;)`,even after this, code was successfully compiled and executed. And I still do not have the answer to my `Ques-1`. If u could please help me here? – phougatv Jun 26 '14 at 02:11
  • 2
    Is this a typo: `num[10] # This value was specifically allocated and initialized.`? The last index allocated was `num[9]` – clcto Jun 26 '14 at 02:15
  • 1
    @VSP see the first comment. That is the section where the standard states that the rest of the fields will be initialized to 0. – clcto Jun 26 '14 at 02:17
  • @clcto OK. Thank u very much for pointing me that out. I just for to go through other comments. Thanks again. – phougatv Jun 26 '14 at 02:24
  • Thanks a lot to everyone. Everyone who pointed out even the slightest thing, commented or gave the answers and the explanations. – phougatv Jun 26 '14 at 02:26