When you write a[4] , it is the same as writing *(a + 4) . Since the compiler does not know how much memory is allocated at the address pointed to by a , it will gladly allow you to access the memory.
However, the memory located there can be anything - it can be another variable used by your program, part of the stack, or simply outside of your program. Accessing the external allocated space in this way is likely to lead (at best) to segmentation failure or (at worst) lead to a security hole by overwriting other parts of your program.
You are correct that you can only assign a[0] or a[1] safely , but the C compiler will allow you to assign external borders (because it knows nothing else),
It is impossible to do a[4] in your example.
Also, it is better not to give the malloc result - see this answer
source share