![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Vyacheslav |
|
||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Earnest, извините. Наверное Ваше сообщение призвано прикратить офтоп, но я рискну продолжить.
Здесь уже вопрос затронут не о применении STL, а о том что уважаемый Mayk пытается неумение написать код списать на якобы имеющиеся недостатки языковых конструкций. С моей точки зрения это просто возмутительно ![]() Итак , уважаемый Mayk, Вы можете пояснить в чем ненадежность данного кода?
Теперь и немного перепишем его, например , воспользуясь auto_ptr. Хотя нет, auto_ptr в данном случае не совсем уместен. Поэтому мы воспользуемся своим. Возможно класса этот немного некорректен, но для демонстрации сойдет
Уверяю Вас, что и в первом и во втором случае код "абсолютно" надежен, несмотря на то что в том и другом случае используются new[] и delete[], написанные ручками , но я, пожалуй, соглашусь, что во втором случае он оказался немного "совершенней" что ли. И если и тот и другой мне попадут на code review я приемлю с удовлетворением и ту и другую версию. Единственное, что я не приемлю, так это наличие "несовершенного кода" с наличем memory leak'ов. И дело тут не в совершенстве, или несовершестве, а банальной ошибке.
Наличие memory leak'ов свидельствует не о том, что код не является совершенным, а том что он написан с ошибками ![]() И будьте уверены, программисту на это будет указано. Ну знаете, а чего же нарываетесь ![]() ![]() -------------------- С уважением, Вячеслав Ермолаев |
||||||
|
|||||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Anikmar, ни один менеджер памяти не рассчитан на такое... специально для этих целей придуманы boost::pool, boost::object_pool, Loki::SmallObj, etc.
Vyacheslav, волшебные контейнеры и смартпоинтеры как правило имеют automatic storage duration и потому автоматически освобождают память как только объект больше не нужен... Добавлено через 8 минут и 51 секунду
не знаю как обстоят дела QT, но в boost для это предусмотрены shared_ptr и shared_array... Добавлено через 11 минут и 55 секунд проглядел... нужно new char [1000] -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Anikmar |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2513 Регистрация: 26.11.2006 Где: Санкт-Петербург Репутация: 9 Всего: 59 |
Это понятно, если конечно приведенные контейнеры реализовывают это не через те же new и delete. Просто vector, например, тут не поможет точно - я смотрел, там все через new и delete сделано, поэтому проблему фрагментации он не снимет. По поводу приведенных классов - ничего не могу сказать, не знаю. Там проблему пришлось решать на сколько я помню именно через свой менеджер памяти. |
|||
|
||||
Vyacheslav |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Естественно ![]() Имелось в виду
по аналогии с первым вариантом -------------------- С уважением, Вячеслав Ермолаев |
||||
|
|||||
archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
неа... vector как раз рассчитан на это... есть такая штука, называется allocator... передаётся вторым или третьим шаблонным параметром вектору... по умолчанию - это std::allocator, который использует new/delete... есть два выхода из этой ситуации: перегрузить операторы new/delete (как это сделано в Loki::SmallObj - просто наследуешь от него и будет использоваться специализированный менеджер памяти), но это не всегда удобно - для int их не перегрузишь... второй вариант - подменить аллокатор... например на boost::pool_aloc Добавлено через 2 минуты и 17 секунд Vyacheslav, и тем не менее... кривость рук в boost исправляется наличием разных смартпоинтеров для разных случаев (new vs new[]) ;) -------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
Gelos |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 21 Регистрация: 29.4.2007 Репутация: нет Всего: нет |
Мда, дискуссия разрослась. Вобщем, немного поясню суть. Как, где-то было выше сказанно, выделялось постоянно в цикле большое колличество блоков памяти. Очень большое. То есть, в файле было около 38000 записей, все они дробились на куски, и под куски выделялась память. И этот файл обрабатывался в цикле тоже около 39 тысяч раз. Проверка пошаговая дебагером показала, что не смотря на то, что ко всем опереторам new вызываются delete к концу обработки вложенного цикла выедается на 6кб. и так дальше.
Причем, конструкция (схематично) была такая while(1) { ukaz = new char[MAX]; ---------- код --------- delete [] ukaz; } После изменения констукции на Bool flag = TRUE; while(1) { if(!flag) { delete [] ukaz; } ukaz = new char[MAX]; flag = FALSE; ---------- код --------- } утечка памяти исчезла. |
|||
|
||||
Vyacheslav |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Все таки останусь при своем мнении: "кривость рук" этим не исправляется, а маскируется. Если Вы не научитесь грамотно писать код, то всякие ссылки типа: "А мне это делать не привык,потому, как за меня это буст делает" вряд ли будут приняты в качестве аргумента в серьезной компании Добавлено через 6 минут и 37 секунд Вообще в своей схеме Вы не указали самый главный момент: где производился выход из бесконечного цикла?. Судя по
явно до вызов последнего вызова delete. Отсюда и утечка -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
archimed7592 |
|
||||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
Vyacheslav, зачем делать класс, который можно будет использовать неправильно, когда можно сделать два класса, которые как не крути - неправильно не поюзаешь... тем более, что в с++ это решается оч простым путём стратегий и два класса делать и не придётся:
что же касается
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
||||
|
|||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Я бы не сказала, что Mayk именно такую позицию защищает. Скорее, это твоя интерпретация его постов. А его проффесионализм и знание C++ у меня сомнений не вызывает. Все, что я видела - это ратование за использование конструкций, облегчающих жизнь программистаи делающих C++ более безопасным. Лично я это тоже приветствую, и сама по другому давно не пишу (т.е. не помню, когда последний раз явно писала delete). Но у меня тоже есть ощущение, что такого рода конструкции скорее помешают начинающему программисту разобраться в языке, чем помогут. В том смысле, что у него просто не будет суровой необходимости, а любопытства может не хватить. Это немного оффтоп, но по моему опыту, программисты, пришедшие из C, лучше въезжают и больше понимают, чем программисты, пришедшие из более высокоуровневых языков типа Жавы. С другой стороны, если в проекте принято использование умных примочек (а я по опыту знаю, насколько это сокращает число потенциальных ошибок), то разрешать кому-то в целях обучения использовать голые new-delete я не собираюсь... -------------------- ... |
|||
|
||||
Gelos |
|
|||
![]() Новичок Профиль Группа: Участник Сообщений: 21 Регистрация: 29.4.2007 Репутация: нет Всего: нет |
Vyacheslav,
Хм, а знаете, может быть и так, хотя, по идее, выход у меня тогда, когда файл закончится. Может там и реально в самом конце выход случается раньше чем остатки выделенной памяти будут скормлены Ктулху... |
|||
|
||||
Vyacheslav |
|
||||||||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Извините, но не стоит придираться к классу, который был написан на коленке для исключительно конкретной демонстрации, причем посредством отнаследования от auto_ptr ![]() ![]()
Мда ? Ну в таком случве исходя из этого совета
Вы не просветите меня , в чем заключается ненадежность new[]/delete[]. А то я их использую, а вдруг мой код из-за них ненадежен? Нехорошо как то получается ![]() Вообще в таком случае "ненадежность" new[]/delete[] я предлагаю решить кардинальным способом: мигрировать на С# ну или в крайнем случае на managed C++. Как Вам такой совет ![]() ![]() А я не мешаю использовать их другим во вполне серьезных проектах. И не уверен, что отсутствие прямого вызова new-delete - признак ученического проекта. Не барское дело ломать стиль программирования своего подчиненного через коленку, даже если и имеешь на это право. Со временем тот и сам поймет, как улучшить свой код. Если программист что-то применяет, то он должен применять это осознанно и по делу, а не потому что без этого он не способен написать грамотный код или потому что начальник сказал, что вот это круто. И кстати , мой Вам респект. Как Вам удается найти на работу столь профессиональный контингент, которые совершенно не требуют обучения? Меня на фирме привлекают очень часто в качестве технического интервьюера при приеме кандидатов и искренне рад, когда из 5 человек хотя бы 1 показывает приемлимый уровень знаний С++ в объеме, ограниченным книгой Страутрупа первого издания.
![]() Ну и возвращаясь к нашей ситуации, когда человек спрашивает, почему у него происходят утечки и получает в ответ
выглядит весьма странно. Я не собираюсь оценивать профессионализм отвечающего, но от совета попахивает немного ламерством Вообще то, задав вопрос
я ожидал, что Mayk уточнит понятие "ненадежности" примерно так, как это сделал Anikmar и статус-кво злосчастных new[]/delete[] и языка С++ в целом было бы восстановлено. Но уважаемый Mayk упорно стал защищать свою первоначальную формулировку, присовокупив к компании ненадежных еще vector ![]() PS Gelos , прошу ни в коем случае не принимать данную дискуссию на свой счет. Это чисто теоретический спор. -------------------- С уважением, Вячеслав Ермолаев |
||||||||||
|
|||||||||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 1 Всего: 260 |
выдержка из книги "Наука отладки": "Изучение знаменитых(и не очень знаменитых) ошибок"
Это к тому, что не стоит настоятельную рекомендацию "более безопасных" конструкций воспринимать как потакание ламеризму и личную обиду ![]() ![]() |
|||
|
||||
v_nikolaev |
|
|||
Новичок Профиль Группа: Участник Сообщений: 38 Регистрация: 6.5.2007 Репутация: нет Всего: нет |
тут, наверное, следует говорить о фрагментации вместе с утечками утечки памяти могут её усугублять: пусть у нас хороший менеджкр хипа, который возвразщает операционке свободный непрерывный участок в конце своей памяти, но всё равно неподчищенная память мешает этому - на следующей фазе программа будет выделять опять то, что было невычищено - это усилит фрагментацию определённым образом. потом мы захотим выделять большие массивы, получится, что у нас нет возможности переиспользовать то, что зарезервировано. я имел дело с прогой в VC, в которой сложилась такая ситуация - из-за невычищенного мегабайта выделялись новые 400M. это также сопровождалось интересным эффектом - d-версия работала быстрее release ![]() но, возможно, дело совсем не в утечках. ещё одна проблема - возможно менеджер хипа не объединяет свободные участки, начинают алокироваться структуры данных большего размера, и переиспользовать память не удаётся. |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
А мне и не удается... Я их учу... А потом они сбегают в Москву, на ЗП, которую наша контора платить не может... :( Да, всегда, если именно контейнер владеет объектами, а не просто хранит ссылки на объекты, живущие в другом месте. Основание: да хотя бы применение удаляющих алгоритмов, типа remove_if. Где потом концы искать, если это динамические указатели? Ваш функтор решит проблему только удаления на деструкторе (и в тех местах, где его можно явно включить - и еще не забыть надо это сделать). Даже если я заранее не уверена, что буду применять алгоритмы, которые могут дублировать или удалять объекты, я все равно предпочитаю безопасные контейнеры, т.к. это проще, чем ломать себе голову, думая о последствиях. Более того, если объекты не полиморфные, я предпочитаю хранить в контейнере именно объекты, а не указатели, и черт с ним, с лишним копированием. Все это позволяет сосредоточиться на алгоритме и логике. Раньше я напрягалась по поводу "лишних" действий, которые придется выполнять бедной железке. И сейчас иногда жаба душит. Но практика показывает, что реальные тормоза возникают вовсе не из-за такой фигни, а скорее из-за плохого, слишком тупого, алгоритма. А чем сложнее алгоритм, тем "самостоятельнее" должны быть данные. Пока он будет сам это понимать, пользователи будут присылать сообщения об ошибке: "ваша программа попросила послать разработчику..." Если трепетно относиться к такому стилю, так что же тогда сказать о манере называть переменные и расставлять скобки? Свов код пусть пишет как хочет (у себя дома), а код в проекте не его, а общий. И, скорее всего, поддерживаться будет совсем другими людьми. А насчет Mayk'а, давай не будем его обсуждать: сам он к спору интерес явно потерял. -------------------- ... |
|||
|
||||
Vyacheslav |
|
||||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
Это как раз определяется внутрикорпоративным стандартом кодирования ![]() ![]()
Это как раз из другой оперы. И какже быть с циклом разработки. в который неотъемлимой частью входит тестирование?
Забыть можно все что угодно, например тот же кошелек дома. Но это еще не повод, чтобы с вечера писать у себя на лбу : "Не забыть взять кошелек " ![]() -------------------- С уважением, Вячеслав Ермолаев |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
2 Пользователей читают эту тему (2 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |