You can solve this mystery with a simple printf:
printf("%zu\n", (size_t)-1U);
This produces 4294967295 (demo) - enough to fill 16Gb of memory on systems where sizeof(int) is equal to 4.
To see why this takes so much space in the file system, compile foo to an object file, and run size utility.
I modified the program to size the array to 1,000,000 elements. Here is the output that you get from running size:
$ gcc -c foo.c
$ size -A -d foo.o
foo.o :
section size addr
__text 0 0
__data 4000000 0
Total 4000000
__data segment contains initialized data. Compiler fills it in because you supplied {1} initializer. If you omit it, the size of the executable on disk would shrink to a few kilobytes, because the array would be placed into uninitialized segment:
$ size -A -d foo.o
foo.o :
section size addr
__text 0 0
Total 0