> В целом абсолютно согласен, но небольшое замечание сделаю > > buf1= new char [10000000]; > > delete buf1; - учите язык > Абсолютно корректно (ну зачем нам деструкторы char-а?). > Более того, в неявном виде я и сам такую запись использую > постоянно: > std::auto_ptr<char> buf(new char[SIZE]);
Хотя в первых книжках Страуструпа и можно прочитать, что delete [] отличается от delete вызовом деструктора для каждого элемента массива (так вел себя cfront), согласно стандарту, поведение delete для памяти, выделенной new[], не определено и вполне может привести к непредсказуемым результатам вплоть до heap corruption - даже для простых типов. Конкретные реализации типа Visual C++ это дело могут прощать (реально все зависит от того, как организовано хранение информации о размере массива), но в общем случае на это лучше не закладываться.
> Просто потому, что векторного auto_ptr-а нет. Другое дело,
Ну есть же shared_ptr/shared_array из boost. Auto_ptr - это вообще хождение по минному полю.
В целом абсолютно согласен, но небольшое замечание сделаю
> buf1= new char [10000000]; > delete buf1; - учите язык
Абсолютно корректно (ну зачем нам деструкторы char-а?). Более того, в неявном виде я и сам такую запись использую постоянно:
std::auto_ptr<char> buf(new char[SIZE]);
Просто потому, что векторного auto_ptr-а нет. Другое дело, что скорее всего просто не знает отличий между скалярным и векторным delete и сделал свой выбор не осознанно (как в вышеприведенном примере), а по незнанию.
Собственно на том же месте другая грубейшая ошибка, которая в данном конкретном случае не приводит ни к чему фатальному
buf1= new char [10000000];
buf3= new char [10000000];
buf= new char [10000000];
//..............
delete buf1;
delete buf3;
delete buf;
//............
delete buf1;
delete buf;
delete buf3;
---
Порядок освобождения ресурсов не просто не обратный - а как бог на душу положит.
Полный разбор делать естественно не буду потому, что на код страшно смотреть - не то, что ковырять
> Структура программы отсутствует как класс. > > Итак по всему коду. Было бы удивительно, если бы все это > работало :))
я тоже раньше так думал05.05.08 14:54 Автор: dl <Dmitry Leonov> Отредактировано 05.05.08 15:47 Количество правок: 5
> В целом абсолютно согласен, но небольшое замечание сделаю > > buf1= new char [10000000]; > > delete buf1; - учите язык > Абсолютно корректно (ну зачем нам деструкторы char-а?). > Более того, в неявном виде я и сам такую запись использую > постоянно: > std::auto_ptr<char> buf(new char[SIZE]);
Хотя в первых книжках Страуструпа и можно прочитать, что delete [] отличается от delete вызовом деструктора для каждого элемента массива (так вел себя cfront), согласно стандарту, поведение delete для памяти, выделенной new[], не определено и вполне может привести к непредсказуемым результатам вплоть до heap corruption - даже для простых типов. Конкретные реализации типа Visual C++ это дело могут прощать (реально все зависит от того, как организовано хранение информации о размере массива), но в общем случае на это лучше не закладываться.
> Просто потому, что векторного auto_ptr-а нет. Другое дело,
Ну есть же shared_ptr/shared_array из boost. Auto_ptr - это вообще хождение по минному полю.
> Хотя в первых книжках Страуструпа и можно прочитать, что > delete [] отличается от delete вызовом деструктора для > каждого элемента массива (так вел себя cfront), согласно > стандарту, поведение delete для памяти, выделенной new[], > не определено и вполне может привести к непредсказуемым > результатам вплоть до heap corruption - даже для простых > типов. Конкретные реализации типа Visual C++ это дело могут > прощать (реально все зависит от того, как организовано > хранение информации о размере массива), но в общем случае > на это лучше не закладываться.
Как то у меня даже мысли не было, что хип может не хранить размер выделенного куска памяти. Собственно именно из-за того, что даже C хранит размеры всех без исключения блоков динамической памяти (для того чтобы работал realloc к примеру) мне даже в голову не приходило, что блок памяти может выделиться без заголовка, ведь как минимум надо ж знать об этой памяти всякую информацию для того, чтобы ее потом освободить. Сейчас подумал и понял, что действительно хип можно реализовать как нибудь настолько убого, что это будет приводить к вышеописанным эффектам, но на самом деле надо будет поковыряться на досуге в стандарте - не зря ж стауструп говорит о деструкторах.
> > Просто потому, что векторного auto_ptr-а нет. Другое > дело, > > Ну есть же shared_ptr/shared_array из boost. Auto_ptr - это > вообще хождение по минному полю.
Да я его кроме хранения буферов памяти нигде и не использую. При работе с объектами мне больше нравятся intrusive_ptr-ы. Кстати, они уже не в бусте а в C++ TR1 (последний feature pack для VS2008 в числе прочего содержит и эти указатели).
по второй ссылке из предыдущего поста это описано05.05.08 16:25 Автор: dl <Dmitry Leonov>
> будет приводить к вышеописанным эффектам, но на самом деле > надо будет поковыряться на досуге в стандарте - не зря ж > стауструп говорит о деструкторах.
Он об этом говорил, когда основной (если не единственной реализацией) была cfront'овская. Потом ради эффективности сделали вариант с over-allocation.
Не нашел в стандарте вообще ничего про скалярный delete, вызванный для вектора (в смысле массива, а не std::vector)05.05.08 17:23 Автор: amirul <Serge> Статус: The Elderman
Значит на усмотрение реализации, что в свою очередь значит - может случиться вообще все что угодно.
> Он об этом говорил, когда основной (если не единственной > реализацией) была cfront'овская. Потом ради эффективности > сделали вариант с over-allocation.
В любом случае спасибо за информацию. Прекращать так делать пока не буду, потому как портирование на другие компиляторы/платформы пока не предвидится, но по крайней мере буду знать откуда ждать проблем.
То есть кто-то должен отладить программу за тебя? :)))28.04.08 18:04 Автор: Den <Денис Т.> Статус: The Elderman