1

I wrote a short program in C just to see what happens when you index past the end of an array.

I found that it mostly produces random values (I know they are not actually random) up until a point (52 indexes past the end in this case) where it produced 0 every single time. Every value past this point and the program crashes. Why is this? is it the end of the programs allocated memory space?

main()
{
    int ar[4];
    ar[0] = 99;
    ar[1] = 45;
    printf("array: %d, %d   random value: %d", ar[0], ar[1], ar[55]);
}

Edit: I also found that if I alter this value that always ends up being 0 (i.e. ar[55] = 1000) then the return code for the program goes up.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
b9703
  • 107
  • 2
  • 11
  • 4
    That's undefined behavior!!! The C language standard does not dictate the behavior of your program following this operation (in oppose to Java `IndexOutOfBound` exception, for example). – barak manos Feb 01 '17 at 06:48
  • http://stackoverflow.com/questions/15646973/how-dangerous-is-it-to-access-an-array-out-of-bounds – M.M Feb 01 '17 at 07:09
  • It fall out the stack, crashes. If you try to read an existent address crashes. If it fall out the heap crashes. If try to write out the bondaryes, damages the memory handler – jurhas Feb 01 '17 at 08:50

2 Answers2

8

... just to see what happens when you index past the end of an array

Trying to access out of bound memory, invokes undefined behavior. Anything can happen, just anything.

In your case, for some reason, the memory address for upto index 52 is accessible from the process, so it allows the access. Index past 52 points to a memory region not allocated to your process address space and thus, raises the access violation leading to segfault. This is not a deterministic behaviour, at all and there's no way you can rely on the output of a program invoking UB.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
4

Accessing array elements beyond array boundaries (before 0 or from its size up) is undefined behavior. It may or may not produce values, it may cause the program to end abruptly, it may cause your system to stop, restart or catch fire...

Modern systems try to confine undefined behavior within reasonable limits via memory protection, user space limitations etc. but even user space code errors can have dire consequences:

  • pacemaker messing with its timing values can cause premature death ;
  • banking software overflowing array boundaries can overwrite account balance information crediting some random account with untold amounts of dollars.
  • your self driving car could behave worse than drunk drivers...
  • think of nuclear power-plant control software, airplane instruments, military stuff...

There is no question undefined behavior should be avoided.

Regarding the exit status, your program uses an obsolete syntax for the definition of main(), implicit return type, which is no longer supported in C99 and later, but does not return anything, which means its return value can be any random value, including a different value for every execution. C99 specified a kludge for the main() function and forces an implicit return 0; at the end of main(), but relying on it is bad style.

Similarly, invoking printf() without a proper prototype is undefined behavior. You should include <stdio.h> before the definition of function main().

Lastly, ar[0] and ar[1] are initialized in main(), but ar[2] and ar[3] are not. Be aware that accessing uninitialized values also has undefined behavior. The values can be anything at all, what you describe as random values, but on some systems, they could be trap values, causing undefined behavior by just reading them.

Some very handy tools are available to track this kind of problems in simple and complex programs, most notably valgrind. If you are curious about this subject, You should definitely look at it.

chqrlie
  • 131,814
  • 10
  • 121
  • 189