1

I was writing code and realized that I can "access" elements of an array that are at the same or greater index than the size of the array. Why doesn't this produce an error?

For example,

#include <iostream>
using namespace std;

int main ()
{
    int b_array[5] = {1, 2, 3, 4, 5};


    cout << b_array[5]  << endl  // Returns 0
         << b_array[66] << endl; // Returns some apparently random value.

    return 0;
}
Robotnik
  • 3,643
  • 3
  • 31
  • 49
ThisIsNotAnId
  • 177
  • 4
  • 20

4 Answers4

7

The only technical answer is "because the C++ language specification say that". Accessing an out-of-bounds value is undefined behavior. Your personal taste are irrelevant.

Behind the "undefined behaviors" (there are many in the C++ specs) there is the need to let compiler developer to implement different optimizations depending on the platform they have to run on.

If you consider that indexes are often used in loops, if you check the bounds, you end up with a check for each iteration, always succeeding (thus wasting processor time).

Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
5

C++ does not implement boundary checking due to the performance penalties that incurs.
For example the vector template contains an at()function which checks for boundary, but is ~5 times slower than the [] operator.
Low-level language tend to force the programmer to produce safe and error free code in return for high performance.

UnholySheep
  • 3,967
  • 4
  • 19
  • 24
3

Although there are simple cases like your where compilers and/or static analyzers could detect that an access is out of bounds, doing it in general at compile-time is not doable. For example, if you pass off your array to a function it immediately decays into a pointer and the compiler has no chance to do bounds checking at compile-time.

The alternative, run-time bounds checking, is comparatively expensive: doing a check upon each access would turn a simple memory dereference into a potentially stalling branch. To make things even harder, you can use the dereference operator on pointers, i.e., you can't even know easily where to locate the size of the actual array object.

As a result, the behavior of out of bounds array accesses is deliberately made undefined: a system can track these accesses but it doesn't have to. Also, what the system actually does upon an out of bounds array access is not specified, i.e., it can do different things depending on the context. In many cases, it will just return junk which isn't really too useful. However, especially with suitable debug settings the system may instead assert() upon detecting a violation.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
3

C++ allows direct memory access to your program. There are no boundary checks done for you. This can be cause of very nasty bugs, but it's also very efficient as compared to other "safer" languages.

An array is nothing but a pointer to a memory location. The index that you are trying to access, such as index 66 in array [66], is resolved by adding 66 * sizeof(int) to the starting address of the array. Whether the finally calculated address is within some bounds or not is beyond the things checked by the compiler.

In other words, array [i] is same as *(array + i) in C++. In fact, you might be surprised that array [i] can also be written as i [array]!

Jaywalker
  • 3,079
  • 3
  • 28
  • 44