Почему не работает обычный delete?

253
15 декабря 2016, 16:14

Вот в этом примере демонстрируется, как создать массив объектов, у которых конструктор принимает параметры. Если мы, как они рекомендуют, отделяем выделение памяти от вызова конструктора, обычный способ очистки уже не сработает, приходится вызывать деструкторы в цикле. Если попытаться написать delete [] foos, всё зависнет.

Но почему?

Answer 1

Если вы выделили память при помощи new[], возвращать её нужно при помощи delete[].

Если же вы выделили область памяти при помощи обыкновенного new, а потом сконструировали объекты при помощи placement new (new( &foos[ i ] ) Foo( a, b );), и освобождать надо так же: placement delete + delete на область памяти. Любое другое освобождение памяти есть по стандарту undefined behaviour, и имеет право вести себя как угодно.

В самом деле: если объект выделен при помощи new, он есть в списке heap-объектов. delete пытается найти вокруг объекта управляющие данные heap'а (например, длину куска памяти), и воспользоваться ими. Если там на самом деле таких данных не найдётся, произойдёт катастрофа. В вашем случае именно это и происходит, только с delete[]. Кроме того, delete[] к тому же пытается вызвать delete для каждого из объектов, для чего ему нужно знать их количество, сохраняемое в управляющем блоке во время new[]. Поскольку new[] не вызывался, всё на самом деле довольно кисло.

Кстати, код, на который вы ссылаетесь, насколько я понимаю, тоже не вполне верен: он считает, что по каждый объект уходит ровно sizeof(Foo) байт памяти, то есть для count объектов нужно sizeof( Foo ) * count байт памяти. Это неверно, если компилятор решит использовать выравнивание. (Например, объект нечётной длины может спровоцировать проблемы.) Вот обсуждение по теме на братском ресурсе.

READ ALSO
Почему с итераторами не сортируется и вылетает?

Почему с итераторами не сортируется и вылетает?

Помогите разобраться с итераторамиПочему с итераторами не сортируется и вылетает?

300
Алгорифм Маркова

Алгорифм Маркова

Подскажите, пожалуйста, встречали ли вы шаблоны к алгорифмам Маркова? Если да, то дайте ссылку на источник

270
Указатель на указатель - что это?

Указатель на указатель - что это?

Часто встречаю вот такую конструкцию:

229
Указатели c++

Указатели c++

В C# я мог использовать свои объекты следующим образом:

253