-1

I have a problem of understanding. Why does this code work? I would now expect to get an out of range error.

int testArray[2][2];

testArray[0][0] = 1;
testArray[0][1] = 1;
testArray[1][0] = 1;
testArray[1][1] = 1;

testArray[1][5] = 5;
std::cout << testArray[1][5];

I am using Visual Studio 2019. I am getting a warning but on the console the correct value is still displayed.

JeJo
  • 30,635
  • 6
  • 49
  • 88
Schlörn
  • 31
  • 3
  • 2
    This is a great example of [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior). Just because your program doesn't happen to crash ... *DOESN'T* mean it's "correct". Nor does it mean it *WON'T* crash at a different time, in a different place, or on a different platform. Or that other "Bad Things" might happen - things that, in the worst case, you might remain blissfully unaware of! EXAMPLE: Suppose you declare a variable after "testArray[]". You've possibly just TRASHED that variable. ALSO: "Managed languages" like C# or Java *MIGHT* give an "out of range" error. – paulsm4 Aug 12 '21 at 05:25

2 Answers2

3

Behavior of your program is undefined!

Why does this code work?

You are accessing the element which is not there. This is simply out of bounds, undefined behavior. Anything can happen, it may or may not print values, but you should not be relaying on it.

If you had used newer compilers, it would have provided some hit regarding this. For instance, clang 12. gives me a clear hint: https://gcc.godbolt.org/z/oar8hqYeb

source > :13 : 5 : warning : array index 5 is past the end of the array(which contains 2 elements)[-Warray - bounds]
testArray[1][5] = 5;
^ ~

gcc 11.1 with -fsanitize=address,undefined flags even tells you what's wrong:

/app/example.cpp:13:19: runtime error: index 5 out of bounds for type 'int [2]'
/app/example.cpp:13:21: runtime error: store to address 0x7ffdcf50a04c with insufficient space for an object of type 'int'
0x7ffdcf50a04c: note: pointer points here
.....

Therefore, be always aware of such undefined behavior cases and write better code which you can relay on!

JeJo
  • 30,635
  • 6
  • 49
  • 88
2

C++ doesn't really check it the index you are trying to access is out of range or not. After compilation, an array is really just a pointer to the first element of the array. Accessing is done by taking the pointer to the first element, add the desired index as address offset to it, then read/write the data at the result address.

In this case, testArray[1][5] = 5; will change something on the stack to be 5. That depends on what's immediately after the array in memory at the time of execution.

By the way, this is called a buffer overflow error, which is a common security issue. In C++, you have the obligation to make sure that array index never exceed it's range. Or else it could lead to unexpected behaviour, crash the program or worse, lead to a remote code execution security issue.

Miigon
  • 779
  • 6
  • 18