Russian Qt Forum
Май 21, 2024, 09:05 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 3 [4]   Вниз
  Печать  
Автор Тема: qDeleteAll - глупый и опасный метод!  (Прочитано 40188 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #45 : Июнь 05, 2012, 14:27 »

Елы-палы. Компилируйте, проверяйте, уважаемый (приаттачка).
Критикуйте СУТЬ топика - неотлавливаемые никак хвосты неинициализированной памяти после применения qDeleteAll.
А Ваш текст компиляции не заслуживает.

1) strncpy не скопирует ноль-терминатор если размер исходной строки превысит m_size - 1. Вылет

2) Ни в печати, ни в init Вы не считаетесь с возможностью NULL-строки, а такой вариант рядовой. Вылет

3) Чего говорить о безопасности если не обеспечиваются конструктор копирования ни оператор присваивания? Такой класс Test - грабли на которые трудно не наступить

4) m_size(20) ... ну что сказать... формально "не ошибка", но профессионализмом и не пахнет

5) по меньшей мере на некоторых платформах realloc не освобождает память (напр realloc(4) не сократит размер блока что был 100k)

и.т.д

И вот Вы напускаетесь на безобидное qDleteAll и требуете от других "чистоты принципов", на которые сами плюете как хотите. Получается "вижу в чужом глазу сучок, а в своем и бревна не замечаю"  Улыбающийся 
Записан
DmitryM
Гость
« Ответ #46 : Июнь 05, 2012, 14:28 »

Variant 1
вот он - сторож контейнера - его размер.
Никак иначе не убедиться, что в контейнере ковыряться ОПАСНО!

Variant 2.
А здесь вы ПОПАЛИ!
Размер вас жестко обманет, и пипец памяти на машине клиента.
Он Вам однозначно скажет спасибо.
Как будете проверять? А??? А???

А почему это у вас контейнер передается не константной ссылкой? А про пред и пост условия вы никогда не слышали?
Записан
DmitryM
Гость
« Ответ #47 : Июнь 05, 2012, 14:31 »

Не понимаю наездов хомячков на qDeleteAll. Он _намеренно_ сделан не очищающим контейнер, чтобы повысить производительность. Нахрена делать deleteAll и потом этот контейнер использовать? Я что-то задач мало вижу реальных. Он либо используется в деструкторе, либо не используется вовсе - в случае поштучной/груповой работы с контейнером.
А в тех случаях, когда нужно переиспользовать контейнер, можно и clear() написать - не обломитесь. С него, кстати, лучше начинать. Если вы напишите qDeleteAll() и забудете clear(), вы быстро об этом узнаете, поверьте.
Вот тебе пример:
Реализуй обобщенный алгоритм перемещающий объекты из одного контейнера в другой. И перемести элементы из std::vector в std::set.
Записан
DmitryM
Гость
« Ответ #48 : Июнь 05, 2012, 14:42 »

.clear() просто должно было быть там по умолчанию в реализации qDeleteAll.
А что будет с итераторами этого контейнера, после вызова .clear()?
Записан
_OLEGator_
Гость
« Ответ #49 : Июнь 05, 2012, 14:45 »

Топик ни о чем. Написать туеву хучу текста, чтобы излить свое недоумение по поводу того, что ТС приходится писать clear() после использования qDeleteAll - это круто.
Всегда есть вариант написать свою реализацию, если что-то не нравится.
Записан
twp
Гость
« Ответ #50 : Июнь 06, 2012, 19:34 »

Поддерживаю _OLEGator_. Вообще с таким же успехом можно придраться к оператору delete который не обнуляет указатель после удаления. То может ТС лучше использовать java или С#
Записан
rp80
Гость
« Ответ #51 : Июнь 07, 2012, 17:57 »


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

"Ваша программа постоянно падает"
"Зато она такая быстрая, что падает чаще других в один и тот же отрезок времени!!"
Ну что ты за упертый тип ппц. Тебе все пытаются втолковать очевидную вещь, что далеко не всегда необходимо чистить контейнер после qDeleteAll. Посмотри пример что я писал выше. Его можно обобщить: очень часто контейнеры указателей используются в качестве локальных или временных объектов. Удалять содержимое необходимо, чтобы предотвратить  утечки памяти, а чистить его вовсе необязательно, он и так будет удален при выходе из области видимости,есть наверняка и другие подобные случаи.
Твои претензии можно с таким же успехом перенести к оператору delete[]. Мол почему он не обнуляет размер массива. Да потому что он и не должен этого делать.
Записан
frostyland
Гость
« Ответ #52 : Июнь 08, 2012, 17:16 »

Когда программист пишет программу, самое главное, о чем он должен думать – это надежность.
Надежность важнее скорости, она важнее даже красоты пользовательского интерфейса. Потому что пользователь скорее простит автору некоторые тормоза и кривизну цветов, нежели потерю данных или GPF в самый неподходящий момент.
И только обеспечив наиболее высокий уровень надежности, можно обратить внимание на скорость. Потому что а) можно удивиться, что скорость вполне устраивает всех, несмотря на то, что про нее не думали, и б) профилирование (именно профилирование) , покажет, что бутылочное горлышко производительности находится совсем не там, где программист предполагал.
После этого очень аккуратно можно заменять участки защищенного кода более безбашенным, но быстрым.

Все написанное выше касается релизного продукта для простых пользователей.
Когда же пишется библиотека для других программистов, требования к надежности должны быть на порядок выше, ибо если можно хоть приблизительно предположить, как рядовой юзер будет пользоваться открытыми интерфейсами программы, то нельзя и близко догадаться, какие фокусы будет вытворять другой программист с библиотекой. Разработчик библиотеки должен учесть самые пессимистические прогнозы использования его продукта другими программистами, так как он делает для них полезный инструмент, а не мину замедленного действия. Причем, руководствоваться следует подходом «Даже если вот это и это маловероятно, все равно я от этого защищаю».

И концепт «не нравится надежность, напиши надежнее» должен быть безусловно заменен на правильный «не нравится скорость, напиши быстрее». А аргумент типа «delete вон тоже такой-сякой» является просто-напросто непрофессиональным подходом, ибо какого черта писать «полезный код» такого же низкого уровня надежности?

Что касается моего «ай-яй-яй» кода, то это называется «прототипирование».
В двух словах, задача такого кода – быстро проверить некоторые идеи, концепты, догадки. Задача очень узкая, делать его надо быстро, потому что главное – не этот код, а проверка, которую он осуществляет. Конечно, в нем много косяков, поэтому пишется он намеренно таким, чтобы не было соблазна потом вставить его в окончательный вариант программы. Для этого есть ряд техник, в  частности, писать на другом языке, обзывать его с префиксом prototype, test, etc…

Про все сказанное можно много где почитать, а я рекомендую отличную книгу Steve McConnell “Code Complete” Second Edition, значение которой в проектировании и написании грамотных программ трудно переоценить. В русском переводе она называется «Совершенный код».

-------------------------------------------------

))) Забавно, что в моих переписках с программистами из англоязычных стран таких рубиловок «Performance over reliability» вообще не возникает. Там это чаще всего вне дискуссий.
Записан
_OLEGator_
Гость
« Ответ #53 : Июнь 08, 2012, 22:30 »

Спасибо конечно за ликбез, но тема яйца выеденного не стоит.

Просьба к админам перенести тему в говорилку.
Записан
Страниц: 1 2 3 [4]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.085 секунд. Запросов: 22.