Требуется, потому что delete будет вызывать деструктор для каждого выделенного элемента, даже для int.
Учтите это:
char * chars = new char[3];
delete [] (int*)chars;
Что будет? Будут названы 3 деструктора для int. Первый для адреса памяти &chars[0]
, второй для &chars[4]
и третий для &chars[8]
. Учтите, что &chars[4]
и &chars[8]
превышают размер выделенной памяти. Хотя деструктор int
в большинстве, если не во всех компиляторах, является фиктивным, это неправильное поведение. А представь, если пишешь
delete [] (Foo*)chars;
, где Foo
имеет деструктор и sizeof(Foo) > sizeof(char)
. Поведение вашей программы будет неопределенным.