3

I Have this C code snippet

int numbers[4]={1};

numbers[0]=1; numbers[1]=2; numbers[3]=3; numbers[10]=4;
printf("numbers: %d %d %d %d %d %d\n",numbers[0],numbers[1],numbers[3],numbers[6],numbers[10],  numbers[5]) ;

The Output for this snippet produces :

    numbers: 1 2 3 963180397 4 0

Well I have couple of questions

  1. wont setting numbers[10] give an error as array is just of size 4 if not then why ( as it didn't give any error )

  2. why printing numbers[6] gives garbage value whereas numbers[5] gives value of 0 ? shouldn't it also be a garbage value.

  3. what effect does setting numbers[10] has i know it does not increases size of array but what does it do then?

Thanks in advance . PS i used GCC to compile the code!!

Alberto Bonsanto
  • 17,556
  • 10
  • 64
  • 93
pyth
  • 451
  • 1
  • 5
  • 12
  • 1
    I'm fairly certain all of this is undefined behavior. Also, just because something is a "garbage" value, doesn't mean it has to look like garbage. `0` can be a garbage value also. – Xymostech Dec 07 '12 at 22:34
  • For the last point, an array in C is nothing more than a pointer to the memory allocated for this array. The type (int, char, whatever) of the array is used by the compiler to know how many bytes the values in the array take. That allows you to target any value using array[offset]. But since it's also a pointer, you can do the same with `*(array + offset)`. _Note: since the addition is commutative, you can also do `*(offset + array)`, which corresponds to `offset[array]`_. If you don't know what a pointer is, I'd suggest you to read this: http://cslibrary.stanford.edu/106/ – 7heo.tk Dec 07 '12 at 23:00

3 Answers3

2
  1. This won't give an error, your array is declared on the stack so what number[10] does is write at the adress number + (10*sizeof int) and overwrites anything that would be there.
  2. As Xymostech said 0 can be as much garbage as 963180397. Printing numbers[6] will print what is stored at the address numbers + (6*sizeof int) so it depends on how your program is compiled, if you have declared local variables before of after numbers, etc.
  3. See answer 1.

What you can do is this :

int empty[100];
int numbers[4]={1};
int empty2[100];

memset(empty, 0xCC, sizeof empty);
memset(empty2, 0xDD, sizeof empty2);

numbers[0]=1;numbers[1]=2;numbers[3]=3;numbers[10]=4;
printf("numbers: %d %d %d %d %d %d\n",numbers[0],numbers[1],numbers[3],numbers[6],numbers[10],  numbers[5]) ;

Now you can understand what you are overwriting when accessing out of your numbers array

koopajah
  • 23,792
  • 9
  • 78
  • 104
  • Is this - http://stackoverflow.com/a/370362/1114457, why you're setting the memory blocks to 0xCC and 0xDD? My question is, why not 0xDD in both? why the 0xCC in first one? – bad_keypoints Jul 06 '13 at 09:05
  • @ronnieaka Not really, I just wanted to initialize the memory before and after the `numbers` array with different values to show where each array starts/ends in memory – koopajah Jul 06 '13 at 18:48
1

To answer your questions:

  1. Not necessarily. The compiler could reserve memory in larger chunks if you declared the array statically or you could have just overwritten whatever else comes after the array on the stack.
  2. That depends on the compiler and falls under "undefined behaviour".
  3. You set (numbers + 10) to the value after the equal sign.
matthias
  • 2,161
  • 15
  • 22
0

It doesn't cause any errors because it is decayed to a pointer arithmetic.

When you write numbers[10], it is just numbers + 10 * sizeof(numbers), which is fairly correct.

It's undefined behavior to access memory you're not meant to (not allocated for you), so every index out of bound that you access is garbage, including 0.

Accessing indexes greater than 4 will not increase the array's size, as you said, and additionally, it does not do anything either.

Toribio
  • 3,963
  • 3
  • 34
  • 48