delete и delete[ ]
От: CompileError  
Дата: 26.01.07 21:38
Оценка:
Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?
Re: delete и delete[ ]
От: Аноним  
Дата: 26.01.07 21:45
Оценка:
да
Re: delete и delete[ ]
От: nrwl  
Дата: 26.01.07 21:55
Оценка:
Здравствуйте, CompileError, Вы писали:

CE>Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?


При условии, что массив объектов создавался с помощью new[] — да.
delete и delete[ ]
От: Андрей Тарасевич Беларусь  
Дата: 26.01.07 22:12
Оценка: +4
#Имя: FAQ.cpp.deletearr
Здравствуйте, CompileError, Вы писали:

CE>Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?


Есль речь идет о массиве в динамической памяти, то удалять его нужно при помощи 'delete[]'. Попытка же удаления через 'delete' ведет к неопределеннному поведению. Именно к неопределеннному поведению. Все.

А всякое "не будут вызваны деструкторы" — это уже гадание на кофейной гуще, к делу никак не относящееся.
Best regards,
Андрей Тарасевич
Re[2]: delete и delete[ ]
От: LaPerouse  
Дата: 26.01.07 23:23
Оценка: -1 :))) :)
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, CompileError, Вы писали:


CE>>Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?


АТ>Есль речь идет о массиве в динамической памяти, то удалять его нужно при помощи 'delete[]'. Попытка же удаления через 'delete' ведет к неопределеннному поведению. Именно к неопределеннному поведению. Все.


АТ>А всякое "не будут вызваны деструкторы" — это уже гадание на кофейной гуще, к делу никак не относящееся.



Вот это-то меня и напрягает в С++. В данном случае логичнее было бы иметь один вид уничтожения объекта (delete), чтобы тем самым уничтожить весь массив, ну, или на худой конец, его первый элемент. Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[3]: delete и delete[ ]
От: Daevaorn Россия  
Дата: 27.01.07 08:40
Оценка: +1
Здравствуйте, LaPerouse, Вы писали:

LP>Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.

А не лучше просто писать правильный код и не сетовать на разработчиков компилятора?
Re[2]: delete и delete[ ]
От: CompileError  
Дата: 27.01.07 09:17
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Здравствуйте, CompileError, Вы писали:


CE>>Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?


АТ>Есль речь идет о массиве в динамической памяти, то удалять его нужно при помощи 'delete[]'. Попытка же удаления через 'delete' ведет к неопределеннному поведению. Именно к неопределеннному поведению. Все.


АТ>А всякое "не будут вызваны деструкторы" — это уже гадание на кофейной гуще, к делу никак не относящееся.


Все понятно, спасибо.
Re: delete и delete[ ]
От: Шахтер Интернет  
Дата: 27.01.07 10:12
Оценка:
Здравствуйте, CompileError, Вы писали:

CE>Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?


На самом деле, весьма вероятно, что произойдет разрушения кучи. Не вызов деструкторов по сравнению с этим -- мелкое хулиганство.

При конструировании массива объектов с нетривиальным деструктором оператором new[] к массиву объектов будет добавлен небольшой префикс, содержащий в частности число элементов массива.
Вернет же оператор указатель на первый элемент массива. Т.е. этот указатель не указывает на первый байт выделенного блока памяти. Поэтому при вызове простого delete ему будет передан неверный указатель на блок памяти, что приведет к разрушению кучи (или к abort у, если куча с защитой).
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[4]: delete и delete[ ]
От: LaPerouse  
Дата: 27.01.07 10:23
Оценка: +1
Здравствуйте, Daevaorn, Вы писали:

D>Здравствуйте, LaPerouse, Вы писали:


LP>>Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.

D>А не лучше просто писать правильный код и не сетовать на разработчиков компилятора?

Не на разработчика компилятора, а на разработчиков стандарта
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[3]: delete и delete[ ]
От: Erop Россия  
Дата: 27.01.07 11:10
Оценка: +1
Здравствуйте, LaPerouse, Вы писали:

LP>Вот это-то меня и напрягает в С++. В данном случае логичнее было бы иметь один вид уничтожения объекта (delete), чтобы тем самым уничтожить весь массив, ну, или на худой конец, его первый элемент. Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.


Да какая проблема?
Пользуйся std::vector, вместо new [] да и всё
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: delete и delete[ ]
От: vasmann  
Дата: 28.01.07 11:42
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Здравствуйте, Daevaorn, Вы писали:


D>>Здравствуйте, LaPerouse, Вы писали:


LP>>>Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.

D>>А не лучше просто писать правильный код и не сетовать на разработчиков компилятора?

LP>Не на разработчика компилятора, а на разработчиков стандарта


А как Вы себе представляете унифицированный опереатор new и delete?
Ведь если вы просто выделяете память то Вам надо просто вернуть указатель, а если блок памяти (читай динамический массив) то помимо указателя нужно выделить еще как минимум 4 байта для храниения кол-ва обьектов. А отсюда вытекает что если вы хотите унифицироавнные опереаторы — то получите всегда дополнительные 4 байта плюс не нужные оператор цикла (даже для одного элемента) — а это НИКОМУ не нада. И действительно что мешает писать правильно? И еще: лучше использовать std::vector — все вопрсы решены. Ну или либу boost (www.boost.org).
Re[6]: delete и delete[ ]
От: Erop Россия  
Дата: 28.01.07 14:56
Оценка: +1
Здравствуйте, vasmann, Вы писали:

V>А как Вы себе представляете унифицированный опереатор new и delete?

V>Ведь если вы просто выделяете память то Вам надо просто вернуть указатель, а если блок памяти (читай динамический массив) то помимо указателя нужно выделить еще как минимум 4 байта для храниения кол-ва обьектов. А отсюда вытекает что если вы хотите унифицироавнные опереаторы — то получите всегда дополнительные 4 байта плюс не нужные оператор цикла (даже для одного элемента) — а это НИКОМУ не нада. И действительно что мешает писать правильно? И еще: лучше использовать std::vector — все вопрсы решены. Ну или либу boost (www.boost.org).


Ну, вообще говоря, проблема в том, что new[] возвращает указатель на первый элемент массива, а не на "массив элементов созданный динамически".

Вообще говоря никто не мешал сделать всё безопасно, но увы, "не в этой очередно йальфа-версии языка С++"
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: delete и delete[ ]
От: LaPerouse  
Дата: 28.01.07 19:02
Оценка:
Здравствуйте, vasmann, Вы писали:

V>Здравствуйте, LaPerouse, Вы писали:


LP>>Здравствуйте, Daevaorn, Вы писали:


D>>>Здравствуйте, LaPerouse, Вы писали:


LP>>>>Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.

D>>>А не лучше просто писать правильный код и не сетовать на разработчиков компилятора?

LP>>Не на разработчика компилятора, а на разработчиков стандарта


V>А как Вы себе представляете унифицированный опереатор new и delete?

V>Ведь если вы просто выделяете память то Вам надо просто вернуть указатель, а если блок памяти (читай динамический массив) то помимо указателя нужно выделить еще как минимум 4 байта для храниения кол-ва обьектов. А отсюда вытекает что если вы хотите унифицироавнные опереаторы — то получите всегда дополнительные 4 байта плюс не нужные оператор цикла (даже для одного элемента) — а это НИКОМУ не нада. И действительно что мешает писать правильно? И еще: лучше использовать std::vector — все вопрсы решены. Ну или либу boost (www.boost.org).

Если я не ошибаюсь, размер массива и так хранится, при условии, что массив расположен в динамической памяти (т е в случае, если delete вообще применим).

Что касается цикла по объектам, то его можно избежать, если трактовать delete именно как уничтожение массива. Как же тогда уничтожить первый элемент? Просто — явным обращением [index], т е это должна быть забота компилятора.

Поправьте. пожалуйста, если ошибаюсь. Мне на самом деле до этого дела нет, т к только std::vector и использую.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re: delete и delete[ ]
От: Vlad_SP  
Дата: 29.01.07 08:57
Оценка:
Здравствуйте, Андрей Тарасевич, Вы писали:

АТ>Попытка же удаления через 'delete' ведет к неопределеннному поведению. Именно к неопределеннному поведению. Все.


Не приведешь ли ссылку на пункт Стандарта, это оговаривающий? Как я ни курил Стандарт, на меня не снизошло просветление... Плохо искал, согласен. Так где же оно?
Re[3]: delete и delete[ ]
От: Left2 Украина  
Дата: 29.01.07 11:18
Оценка: +1
LP>Вот это-то меня и напрягает в С++. В данном случае логичнее было бы иметь один вид уничтожения объекта (delete), чтобы тем самым уничтожить весь массив, ну, или на худой конец, его первый элемент. Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.

Предлагаю как кардинальную меру не юзать ни delete[] ни delete вообще — и никогда не возникнет таких проблем
Если нужен динамический массив — юзайте std::vector (в крайнем случае — его самописный аналог).
Если нужен одиночный обьект, создаваемый динамически — то std::auto_ptr, boost::shared_ptr, ATL::CComPtr — ну или самописный аналог на крайняк. Оверхед нулевой или минимальный, а преимущества очевидны.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: delete и delete[ ]
От: Vlad_SP  
Дата: 29.01.07 11:24
Оценка:
Сорри, разобрался. 5.3.5 cl. 2.
Re[4]: delete и delete[ ]
От: Zigmar Израиль  
Дата: 29.01.07 13:19
Оценка: :)
Здравствуйте, Left2, Вы писали:
L>Предлагаю как кардинальную меру не юзать ни delete[] ни delete вообще — и никогда не возникнет таких проблем
L>Если нужен динамический массив — юзайте std::vector (в крайнем случае — его самописный аналог).
L>Если нужен одиночный обьект, создаваемый динамически — то std::auto_ptr, boost::shared_ptr, ATL::CComPtr — ну или самописный аналог на крайняк. Оверхед нулевой или минимальный, а преимущества очевидны.
Вот чего я-бы категорически не советовал делать, так это хранить указатель на динамический массив в std::auto_ptr или boost::shared_ptr. Это как раз таже-самая проблема, с которой началась тема. auto_ptr всегда удаляет объекты через delete (не delete[]!) а shared_ptr — по умолчанию. Так что std::auto_ptr(new int[100]) это самый что не наесть UB. Если нужен автоматический контейнер для дин. массива, курите boost::scoped_array и boost::shared_array.
"To protect people you must slay people. To let people live you must let people die. This is the true teaching of the sword."
-Seijuro Hiko, "Rurouni Kensin"
Re[5]: delete и delete[ ]
От: Left2 Украина  
Дата: 29.01.07 13:25
Оценка:
Z>Вот чего я-бы категорически не советовал делать, так это хранить указатель на динамический массив в std::auto_ptr или boost::shared_ptr. Это как раз таже-самая проблема, с которой началась тема. auto_ptr всегда удаляет объекты через delete (не delete[]!) а shared_ptr — по умолчанию. Так что std::auto_ptr(new int[100]) это самый что не наесть UB. Если нужен автоматический контейнер для дин. массива, курите boost::scoped_array и boost::shared_array.
а где в моём сообщении призыв хранить массивы в auto_ptr/shared_ptr ?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: delete и delete[ ]
От: LaPerouse  
Дата: 29.01.07 20:23
Оценка:
Здравствуйте, Left2, Вы писали:

LP>>Вот это-то меня и напрягает в С++. В данном случае логичнее было бы иметь один вид уничтожения объекта (delete), чтобы тем самым уничтожить весь массив, ну, или на худой конец, его первый элемент. Вместо — этого — неопределенность, которую каждый разработчик компиляторов трактует по своему. GCC, например, грохает первый элемент. Меня, например, это начинает доставать.


L>Предлагаю как кардинальную меру не юзать ни delete[] ни delete вообще — и никогда не возникнет таких проблем

L>Если нужен динамический массив — юзайте std::vector (в крайнем случае — его самописный аналог).
L>Если нужен одиночный обьект, создаваемый динамически — то std::auto_ptr, boost::shared_ptr, ATL::CComPtr — ну или самописный аналог на крайняк. Оверхед нулевой или минимальный, а преимущества очевидны.


Кажется, тут мои слова восприняли буквально. "Это" — означает, само собой, не конкретно вот это, а такой вот подход — когда что-то неопределено, а разработчики компиляторов реализуют каждый так, как понимает.
Социализм — это власть трудящихся и централизованная плановая экономика.
Re: delete и delete[ ]
От: Critical Error ICQ: 123736611
Дата: 30.01.07 09:28
Оценка: -3 :)
Здравствуйте, CompileError, Вы писали:

CE>Правда ли, что если создать массив объектов, то при его удалении с помощью операции delete не будут вызваны деструкторы для каждого из элементов массива (обязательно надо использовать delete[ ] )?


При удалении массива объектов с помощью delete[] сначала запускается цикл, который тупо берет адрес массива, затем вызывает деструктор, прибавляет к адресу размер элемента и гоняет цикл пока не выйдет за границу массива.

Так что создан массив с помощью new[] или просто malloc()-ом не важно. Поведение delete и delete[] довольно предсказуемо. Поэтому когда не уверен будет ли в точке удаления один объект или массив объектов, лучше применять delete[]. Если там один элемент — ничего страшного, вызовется деструктор один раз, потеряешь только пару машинных тактов на обработку цикла. Зато никакой неопределенности не будет. Тем более, кто компилятор сам иногда оптимизирует код, превращая delete[] в delete когда надо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.