АТ>Таким образом, выделяя память через 'new int[8]', мы просим и получаем от RTL блок памяти в '8 * sizeof(int)' байтов или несколько больше и RTL где-то запоминает размер этого блока. Обычно это делается в самом блоке, "слева" от возвращенного указателя, т.е. фактически размер выделенного блока будет еще, скажем, на 4 байта больше (будем считать что наша платформа использует 4 байта для хранения размера блоков сырой памяти). Запоминать же размер массива в элементах в этом случае не надо, т.к. тип 'int' не требует деструктирования.
АТ>Выделяя же память через 'new C[8]' (где C — класс с нетривиальным деструктором) в традиционной реализации мы (с точки зрения 'operator new') просим у RTL блок памяти длиной в '8 * sizeof(C) + 4' байт. Эта подсистема даст нам такой блок (или больше) не забыв запомнить его размер в байтах "слева" от возвращенного указателя. Реализация 'new[]' же использует первые 4 байта этого блока для запоминания размера массива, т.е. запишет туда 8, сконструирует в остальной памяти 8 элементов и вернет нам указатель на первый из них. Т.е. в этом случае "слева" от возвращенного указателя хранится два размера — размер массива в элементах и размер блока памяти в байтах.
Хорошо, т.е. вы хотите сказать, что вот в таком коде
class C
{
int v;
~C(){}
};
void f()
{
C* ptr = new C[100];
delete[] (int*)ptr;
}
компилятор просто не сможет правильно вычислить адрес начала "сырой" выделеной памяти и, попросту говоря, всё хлопнеться?
А вы сможете подтвердить такое поведение пунктом стандарта?