Эд и Экс правы, но под капотом происходит гораздо больше.
Если вы используете new, а затем delete, вызов delete выполнит один деструктор.
Если вы используете new [], вы должны использовать delete [], но как delete [] знает, сколько деструкторов нужно вызвать? Может быть массив из 2 экземпляров или один из 2000 экземпляров?
Что делают некоторые (возможно, большинство или все) компиляторы, так это сохраняют количество экземпляров непосредственно перед возвратом памяти.
Так что, если вы вызовете new [5], то new выделит память следующим образом:
+---+-----------+-----------+-----------+-----------+-----------+
| 5 | instance1 | instance2 | instance3 | instance4 | instance5 |
+---+-----------+-----------+-----------+-----------+-----------+
И вы получаете указатель обратно на instance1.
Если вы позже вызовете delete [], delete [] будет использовать номер (в данном случае 5), чтобы увидеть, сколько деструкторов нужно вызвать, прежде чем освободить память.
Обратите внимание, что если вы смешаете новое с delete [] или new [] с delete, это может пойти ужасно неправильно, потому что номер может отсутствовать или номер может быть неправильным.
Если смешивать new [1] с delete delete, возможно, вам просто повезло, но не надейтесь на это.