It is true that x
is a pointer, but it is a pointer to a block that can hold a maximum of 10 integer values. Arrays, in C, technically work the same way; an array name's decay to a pointer to the array (the block) and the bracket notation is just a syntactic sugar for some pointer arithmetic that is done underneath the hood.
So now that you know that the bracket notation is a syntactic sugar, what really happens when you do something like x[10]
is something like *(x + 10)
.
If we assume that x
stores the address 100 and that an int
is 4 bytes long on the appliance, then *(x + 10)
basically means *"add 10 * 4 to the value of x
and grab the value that is in this new address"*. So this technically tries to get the int
value that lives in a 4-byte memory block whose starting address is 140.
So far so good! Recall that an int
is 4 bytes long. Now the question is, do the bytes 140, 141, 142, and 143 (i.e., the 4 bytes that store the int value that we are trying to get) really belong to the 40-byte long block that is pointed to by x
, which recall stores the starting address of this block which is address 100?
Let's see, with a bit of visualization whether the 4-byte block whose starting address is 140 belongs to our 40-byte block that is pointed to by x
or not
+++++++++++++++++++++++++++++++++++++++++++++
| x |
| 1st int 2nd int 3rd int ... 10th int|
| +++++++ +++++++ +++++++ +++++++ |
| | | | | | | | | |
| | | | | | | | | |
| +++++++ +++++++ +++++++ +++++++ |
| 100-103 104-107 108-111 ... 136-139 |
+++++++++++++++++++++++++++++++++++++++++++++
Now it's clearer that x[10]
is out of our array's bounds!