Почему в массив размером N можно положить больше чем N элементов?
Потому что в языке Си вы сами должны контролировать работу с памятью и следить, чтобы не происходило записи за пределы массива, переполнения стека и т.д.

В данном случае из-за такой записи за границы допустимого возможны любые глюки вплоть до падения программы.
В malloc при передаче в качестве аргумента нуля возвращаемое значение не определено (implementation-defined). Так что фиг знает что там вам вернул маллок. Но раз программа не падает, то, возможно, он вернул какой-то указатель на стек, а в стеке у вас есть ~8МБ - развлекайтесь.
В общем не нужно так делать. На другом компиляторе (или на том же, но другой версии) поведение может быть совсем другим.