Здравствуйте, Аноним, Вы писали:
S>>если ты вызываешь new[], то удалять надо при помощи delete [].
А>для простых типов да и для структур и классов в которых в деструкторе ничего не происходит, можно delete [] не писать.
Это особенность реализации некоторых компиляторов. И только!!!
Закладываться на это нехорошо!!!
Одним из способов реализации new[] delete[] является следующий. Если у объектов, создаваемых по new[] есть нетривиальный деструктор, то аллокируется память с запасом, в начало памяти кладут счётчик объектов (чтобы потом вызвать деструкторы у нужного числа объектов), а объекты располагают за этим счётчиком. Ну и из выражения new T[count] возвращают указатель не на начало блока, а на первый из объектов.
Соответсвенно, когда ты делаешь delete[], то в зависимости от того, есть ли у типа тривиальный dtor ищут счётчик перед переданным в delete[] адресом или нет. И освобождают блок, соотетветственно, либо начинающийся с адреса первого объекта, либо начинающийся раньше. А выражение delete p сразу считает, что блок начинается с того адреса, откуда начинается объект.
Конечно, если разрушается массив объектов, про деструктор которого такая реализация решила, что они имеют тривиальный деструктор, то всё будет хорошо. Но если она вдруг от чего-то подумает иначе, то ты попробуешь удалить адрес, находящийся в сериедине блока -- это капец куче
Можешь попробовать на "дефолтном компиляторе" что-то вроде следующего:
struct SCrashBase {
virtual ~SCrash() {}
};
struct SCrash : SCrashBase {};
void foo( int count )
{
delete new SCrash[count];
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском