0

I have this code:

#include <stdio.h> 
int main()
{
    int arr2[5];
    arr2[0] = 0;
    arr2[1] = 1;
    arr2[2] = 2;
    arr2[3] = 3;
    int arr3[5] = {1, 2, 3, 4};
}

And when I'm printing the fifth position of each array I'm getting different results:

printf("Fifth: %d\n", arr2[4]); // Prints Random number 
printf("Fifth: %d\n", arr3[4]); // Prints Zero!

output:

Fifth: -858993460
Fifth: 0

I understand that the first is a pointer to the location of the fifth in the memory, and the second one is just how the array was initialized with 0. I don't understand why they give me 2 different values. I have set the size of the array to 5 in both cases; why is this happening?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Eladtopaz
  • 1,036
  • 1
  • 6
  • 21
  • 1
    `{}` actually initializes all array members, while leaving `arr2[5]` just allocates and does not initialize. You are accessing an unitialized array member, which is undefined behaviour. – Raildex Dec 03 '21 at 12:16

3 Answers3

5

With

int arr2[5];
arr2[0] = 0;
arr2[1] = 1;
arr2[2] = 2;
arr2[3] = 3;

you don't actually initialize the array. You create it uninitialized and with indeterminate values for each element. Then you assign to four separate elements, leaving the fifth uninitialized.

On the other hand, with

int arr3[5] = {1, 2, 3, 4};

you explicitly initialize all elements. The first four with explicit values, and then the remaining (single, for this specific array) elements with zero.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
4

A local variable which isn't initialized explicitly gets indeterminate values, "garbage" if you will. Printing an indeterminate value is unspecified behavior, meaning that the output may not follow any logic at all. You might even get different values each time your print the same uninitialized location.

In some cases, accessing an uninitialized local variable is even undefined behavior - see (Why) is using an uninitialized variable undefined behavior?

Initialization in C happens at the same line as variable declaration. Since there is no = on the line int arr2[5];, there is no initialization taking place. The following lines below that one is not initialization, but assignment in run-time. And you left out the final item, so it remains indeterminate.

However, in case an array is partially initialized, the rest of the items in the array get implicitly initialized "as if they had static storage duration", which in practice means that they get set to zero and that behavior is well-defined.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Passing indeterminate values to library functions is UB (by omission in the standard; [DR451](http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_451.htm) specified it to be UB). – M.M Dec 03 '21 at 12:40
  • @M.M Yes I recall hearing about something like that. Though in this case, the more relevant part is accessing an uninitialized local variable which does not have its address taken (see the link), which is always UB. It doesn't apply to arrays accessed with `[]` though. – Lundin Dec 03 '21 at 14:03
  • `printf` is a library function – M.M Dec 03 '21 at 14:05
  • @M.M Yeah well the DR you mention didn't make it to C17 nor did their "wobbly type" discussed in the DR. There is no mentioning in the actual standard what will happen if you pass an indeterminate value to a library function. – Lundin Dec 03 '21 at 14:09
  • Undefined by omission, then. But I think we can take committee resolutions as indicative of intent – M.M Dec 03 '21 at 14:12
  • @M.M Making things undefined behavior when there is no underlying technical reason isn't helpful. That's exactly how C ended up with the complete mess of signedness formats, padding bits with traps and other nonsense which has no relevance in real-world computers. Similarly, reading a random value from the uninitialized stack doesn't cause any computer I can think of to crash. -> – Lundin Dec 03 '21 at 14:22
  • Stating something as undefined while it's actually merely unspecified in real-world hardware is an open invitation to compiler vendors to create misguided optimiziations breaking programs that could otherwise "limp home", displaying nonsense but at least not blowing up or cause dangerous situations. – Lundin Dec 03 '21 at 14:22
0

Your data is on the stack. For such variables the standard does not guarantee an initial value (so it is undefined). You did not initialize arr2[4], and you are getting a value for which the standard does not provide any guarantee, so they could be literally anything.

D-FENS
  • 1,438
  • 8
  • 21