This is undefined behaviour.
Behind the scenes
What's going on behind the scenes is that 5 int
s are allocated on the stack. Lets say they're put at address 0x20
to 0x30
. The array notation []
is really syntax sugar for using pointers. This means that arr[0]
really is a pointer to 0x20
. Your array in this case translates to the following addresses (because sizeof(int) = 4
):
arr[0]
= (arr+0)
= 0x20
arr[1]
= (arr+1)
= 0x24
arr[2]
= (arr+2)
= 0x28
arr[3]
= (arr+3)
= 0x2C
arr[4]
= (arr+4)
= 0x30
This is all fine and good, you're operating on allocated memory. What happens when you try to write to index 5? Well, the same thing, basically:
arr[5]
= (arr+5)
= 0x34
.
It's still just a pointer to an address that you want to write to. The problem is, however, that you haven't told anyone that you intend to write to that address - the memory has not been set aside for you.
If it has not been set aside for anything else, this will likely turn out alright - as you observe.
However if it has it can turn into all sorts of strange behavior depending on what it was used for. Maybe it has been set aside and is just not used yet, maybe it has been used but is simply overwritten and will not be checked again. The point is we don't know! Therefore it is dangerous and undefined.
The reason why it even works in the first place, is that - again - it is just dereferencing a pointer. And dereferencing a pointer should work, as you're trusted to know more that the compiler. It may warn you that you probably shouldn't do this, but it's not an error per se.
What you should do instead
When working with variable length arrays in C++, one should use the modern tools available since C++11. In this scenario, it's advisable to use std::vector
instead. If you use the at
function rather than []
it checks whether the index is inside the bounds.