Черт, я пропустил весь вопрос, но я оставлю свой первоначальный ответ в виде sidenote. Почему мы удалили [], потому что давным-давно мы удалили [cnt], даже сегодня, если вы пишете delete [9] или delete [cnt], компилятор просто игнорирует то, что находится между [], но компилируется нормально. В то время C ++ сначала обрабатывался внешним интерфейсом, а затем передавался обычному компилятору C. Они не могли хранить трюк где-то под занавесом, может быть, они даже не могли думать об этом в то время. А для обратной совместимости, компиляторы, скорее всего, использовали значение, указанное между [], в качестве счетчика массива, если такого значения нет, то они получают счетчик из префикса, поэтому он работал в обоих направлениях. Позже мы ничего не печатали между [] и все работало. Сегодня я не думаю, что «delete []» необходимо, но реализации требуют этого.
Мой оригинальный ответ (который не соответствует сути) ::
«удалить» удаляет один объект. «delete []» удаляет массив объектов. Чтобы delete [] работал, реализация хранит количество элементов в массиве. Я просто дважды проверил это, отлаживая код ASM. В проверенной реализации (VS2005) счет был сохранен как префикс к массиву объектов.
Если вы используете «delete []» для одного объекта, переменная count является мусором, поэтому код падает. Если вы используете «delete» для массива объектов из-за некоторой несогласованности, код падает. Я проверял эти случаи только сейчас!
"delete просто удаляет память, выделенную для массива." Утверждение в другом ответе не правильно. Если объект является классом, delete вызовет DTOR. Просто поместите точку останова в код DTOR и удалите объект, точка останова попадет.
Что мне пришло в голову, так это то, что если бы компилятор и библиотеки предполагали, что все объекты, выделенные «new», являются объектными массивами, было бы нормально вызвать «delete» для отдельных объектов или массивов объектов. Отдельные объекты просто были бы особым случаем массива объектов, имеющего счет 1. Может быть, что-то мне не хватает, в любом случае ...