int a[2];
means "allocate memory that is 2 * sizeof(int)
"
a[5]
is syntactic sugar for *(a + 5)
, which point to an area of memory a + (5 * sizeof(int))
. So 3 * sizeof(int)
past the end of your array. Where is that? Who knows?
Some languages do bound checking, and I have heard of some C compilers that can do it as well, but most do not. Why not do bound checking? Performance. And performance is a major reason for using C in the first place. But that's OK, because C programmers are good programmers and never go beyond the bounds of an array. (hopefully)