Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Работа оператора delete[] |
Автор: Gelos 1.5.2007, 14:10 |
Прочитал темы посвещенные данному оператору, но то что интересует не нашел. В случае, если я просто вызываю оператор delete [] mass; то соотвественно , все что было в этой памяти уничтожается, но что происходит с памятью? У меня есть подозрение, что освобожденная память не возвращается обратно в систему. А дальше по циклу, я снова выделяю память, по этому же указателю, и так пока программа не съедает все виртуальную память на машине, и благополучно умирает. Сегодня наткнулся на запись в книге, что, для того чтобы освобожденная память была возвращена в систему, оператор delete помещается в деструктор. Так ли это? или в любом случае , освобожденная память возвращается в систему? |
Автор: sergejzr 1.5.2007, 14:16 |
"Возвращается" конечно. Освобождённые блоки помечаются свободными и будут использованы при первом удобном случае. А с чем связано подозрение? |
Автор: Xenon 1.5.2007, 14:16 |
Память выделенную с new T удаяешь при помощи delete pTr, а new T[] удаляешь delete [] pTr. Если попытаешься стереть то, что выделил с new [] простым delete, то получишь UB. И что значит не возвращаться в память? При вызове delete вызывается деструктор, а потом free, который освобождает память. |
Автор: Gelos 1.5.2007, 14:33 |
Подозрение связано с тем, что очень хорошо в диспетчере задач видно , как программа выедает память. При отладке в дебагере видно, что данные уничтожаются. И тем не менее, память исчезает. Поэтому и возникла мысль, что освобожденная память так и остается освобожденной областью памяти, в которой ничего нет, а на следующей итерации цикла, где снова вызывается оператор new память опять выделяется, и данные записываются в неё, а не в ту ранее освобожденную область . |
Автор: Romikgy 1.5.2007, 14:37 |
имхо где то есть участок кода где есть выделение памяти , но нет освобождения |
Автор: Gelos 1.5.2007, 15:00 |
Romikgy, ладно... придется дальше искать. Значит, при операторе delete память "возвращается в общий кусок" а не остается висеть в пространстве пустой областью просто занимающей место. Так? |
Автор: Romikgy 1.5.2007, 15:43 |
так |
Автор: Rockie 1.5.2007, 18:31 | ||
Gelos, покажи код, а то так ты можешь еще очень долго выяснять |
Автор: Mayk 1.5.2007, 18:46 | ||
Найди какой-нибудь инструмент, отлавливающий memory-leak'и. Или свой напиши --- перегружаешь операторы new и delete, при вызове new записываешь куда-либо что было выделение. При вызове delete'ов затираешь что было выделение. В конце работы выводишь какие участки памяти не были освобождены. |
Автор: Gelos 1.5.2007, 19:32 |
Rockie, Код проекта уже весьма большой, поэтому приводить не имеет смысла. Mayk, Спасибо, возьму на заметку. хорошая идея.. |
Автор: Rockie 1.5.2007, 19:50 |
а, блин ![]() Семен Семеныч.. ![]() Добавлено через 4 минуты и 4 секунды Gelos, ты выделяешь память в цикле, но навряд ли там же освобождаешь. В итоге память выделяется, не удаляется и снова выделяется. Поэтому программа жрет память, что и должна делать ![]() |
Автор: Gelos 1.5.2007, 20:18 |
Rockie, ну щаз ) как же. в обоих циклах, как в главном так и вложенном память выделяется и там же уничтожается. ![]() |
Автор: Rockie 1.5.2007, 21:04 | ||
Gelos, чего ты жадничаешь? покажи функцию с этими циклами)) |
Автор: Gelos 1.5.2007, 22:13 |
Rockie, кхе.... Да дело не в жадности. Просто весь проект взаимосвязан. Я не могу от туда взять кусок, и и показать. Мол тут непонятно. А выкладывать весь код, я редактировать устану. |
Автор: Xenon 1.5.2007, 22:17 |
Тогда и мы вряд ли чем поможем ![]() |
Автор: Mayk 1.5.2007, 22:52 | ||
а обязательно использовать эти ненадёжные new[]/delete[]'ы? контейнеры и smart pointerы не пойдут?
Кстати. А утечка памяти происходит именно в этих циклах? А не в других ф-циях, вызываемых из этих циклов? |
Автор: Gelos 1.5.2007, 23:01 |
Mayk, Функция одна. она же главная. Я не стал заводить множество функций под каждую операцию в проекте, хоть и признаю, что самым лучшим тоном было бы создать одну функцию, которую бы вызывал с разными параметрами. Ну да не будем переходить к специфике проекта самого. И... Как узнаю и научусь пользоваться контейнерами и smart pointerами то обязательно сравню чем лучше. На данный момент, это для меня неизвестные термины. Все ещё впереди. Xenon, Уже помогли. Причем достаточно сильно. Спасибо. |
Автор: Vyacheslav 2.5.2007, 13:37 | ||
А где в стандарте описывается вероятность, с которой должен "ненадёжный" delete[] должен освобожать память выделенную "ненадёжным" new[] ![]() И чем, простите, пользуются Ваши волшебные "контейнеры и smart pointerы", что бы избежать этой ненадежности ![]() |
Автор: Anikmar 2.5.2007, 14:18 | ||
Пожалуй слово "ненадежный" надо употреблять к программеру. Я так понял суть вопроса была в нехватке памяти. Где-то с год назад в другом формуе была похожая проблема. Весь вопрос был в том, что в процессе работы выделялось огромное количество небольших кусочков, потом освобождалось, потом снова выделялось. Я написал небольшой тест (сейчас найти его не смог). Программа только и делала, что выделяла и освобождала небольшие участки памяти. Стабильный вылет по нехватке памяти примерно через 10 минут работы. Естественно все корректно освобождалось - там ошибиться было негде. Тогда все на форуме пришли к дружному мнению, что менеджер памяти в Борланде оказался не готов к таким вещам. Но чтобы это достичь, понадобилось действительно очень много раз выделять и освобождать много кусочков. А вот куда тестовый код дел - Бог его знает, видимо затер... |
Автор: Mayk 2.5.2007, 18:28 | ||||
Извиняюсь за такую банальность --- деструкторами( которым обычные указатели, кстати, не могут похвастать). Ненадежность пары new/delete заключается в том, что их надо писать руками. А если не напишешь --- то получишь memory leak. Контейнеры и смарт поинтеры умеют пытаются чистить память самостоятельно. Зачастую довольно успешно. Или я что-то пропустил и теперь без явного my_vector.clear() память контейнеры уже не освобождают? ![]()
А Вы видели код автора темы? Откуда такая уверенность что на каждый new[] имеется delete[]? |
Автор: Ken 2.5.2007, 19:10 | ||||
Если память выделяется и освобождается внутри одной функции и еще размер массивов не очень большой то можете выделить ее в стеке. Это работает очень быстро и автоматом очищается. Например:
Оператор new и delete не очень легкие операции. При частом использовании в некоторых случаях может провести к фрагментации адресного пространства процесса. Но этого (многократного создания и удаления) можно избежать, например таким образом:
|
Автор: Earnest 2.5.2007, 19:11 |
А не ищете ли вы в темной комнате черную кошку которой там нет Откуда уверенность, что есть утечки? Менеджер процессов показывает только возрастание? Так он за такими мелочами, как отдельные кусочки в хипе не следит, хотя бы потому, что управление хипом может по разному происходить в разных программах. Кроме утечек есть ведь такая вещь, как фрагментация памяти... Т.е. выделенный объем хипа большой, а память в нем нарезана мелкими дольками: и свободной вроде много, и непрерывный кусок не найти... |
Автор: Vyacheslav 2.5.2007, 19:54 | ||||||||
Ничего страшного, я Вас извиняю. Но продолжим дальше. А чем пользуются деструкторы, что осободить память? delete[] не предлагать в виду его "ненадежности" ![]()
Валим с больной головы программиста на здоровую оператора ? В чем же виноват бедный оператор , если у программиста кривые ручки?
"Зачастую довольно успешно." Как ? И они тоже проявляют ненадежность?
Ну Вы тоже его не видели. Но даже если это и так, то я считаю, что неправильно лечить кривизну рук применением приемов и идиом программирования. Ни на квалификации, ни на качестве кода это в конечном счете не скажется. Код останется таким же сомнительным. Что же касается темы топика, то выскажу мысль о том, что судить об утечках основываясь на показаниях менеджера процессов, не кажется мне достаточно разумным. |
Автор: Mayk 2.5.2007, 20:47 | ||||||||||||
я ж уже написал что
Забыть вызвать деструкторы весьма проблематично. Забыть вызвать delete[]/free()/fclose/pthread_mutex_unlock/etc достаточно легко. Особенно в громоздкой ф-ции.
В неудобстве использования. Или Вы в самом деле считаете, что явный вызов delete[] является верхом удобства?
Поиск по ключевым словам "циклическая зависимость"(это о не абсолютной надежности смарт поинтеров) и обдумывание vector<int*> mv(1, new int[100]); return; (это о не абсолютной надежности при использовании контейнеров)
Я оптимистично считаю, что а) недостаток опыта является временным явлением б) применение приемов и идиом программирования позволяет сократить кол-во потенциальных ошибок. (не говоря уже о том что изучение соответствующей литературы очень навряд ли скажется отрицательным образом на квалификации и качестве кода)
К сожалению других данных у нас нет. Но лишний прогон через детекторы memory leak'ов хуже не сделает. |
Автор: Rockie 2.5.2007, 21:14 | ||||||
Судя по
возможно автар создал нечто вроде
хотя как оно было на самом деле мы уже вряд ли узнаем)) |
Автор: vinter 2.5.2007, 21:16 | ||
это проблемы программиста, он не должен забывать. |
Автор: Vyacheslav 2.5.2007, 21:16 | ||||
Вы знаете, Я в полной растеренности. Вы действительно уверены, что vector предназначен для только для того, чтобы уберечь неокрепшие души начинающих программистов от написание ужасного delete? Потому как в этом коде,
я вижу , как создается вектор указателей на инт размером 1 и тут же инициализируется адресом на массив, выделенный оператором new[]. Насколько я понимаю, здесь мы имеем возможность наблюдать ту же кривизну рук. Почему Вы это отнесли этот код к " не абсолютной надежности при использовании контейнеров" для меня загадка |
Автор: Mayk 2.5.2007, 21:53 | ||||||||||
угу, только удобства это не добавляет. RAII же эту проблему решает достаточно элегантно. я уже не помню когда в последний раз писал close() для закрытия файлов.
Предоставьте ссылку на пост где я писал что он предназначен только для этого.
По определению
Наличие memory leak'ов свидетельствует о том, что код не является соврешенным, следовательно он не является абсолютно надёжным в плане памяти несмотря несмотря на использование контейнера. Напомню что это было к реплике
Вот подобный пример как раз показывает когда stl'овские контейнеры проявляют ненадежность. Для примера --- QPtrCollection из QT(это базовый тип для коллекций указателей) имеет свойство autoDelete, при установке которого элементы данного контейнера будут delete'нуты. (знаю-знаю, delete отличается от delete[] --- суть не в этом, суть в том что иногда контейнер вполне успешно может контролировать жить элементам, или нет). |
Автор: Earnest 3.5.2007, 07:17 |
Mayk, Vyacheslav, я как-то упустила нить вашей дискуссии... Да и не только я, полагаю... ![]() Вы оба правы: хорошему программисту STL контейнеры, RAII и прочая, конечно, не помешают, но плохому - не помогут... Стоит только посмотреть (да хотя бы по этому форуму), ЧТО народ пытается в контейнеры засунуть... ![]() Кривые руки одним использованием STL не выпрямляются... Даже наоборот, появляется искусс и дальше ничего не понимать... Пороть надо, наверное... ![]() |
Автор: Vyacheslav 3.5.2007, 12:09 | ||||||||
Earnest, извините. Наверное Ваше сообщение призвано прикратить офтоп, но я рискну продолжить. Здесь уже вопрос затронут не о применении STL, а о том что уважаемый Mayk пытается неумение написать код списать на якобы имеющиеся недостатки языковых конструкций. С моей точки зрения это просто возмутительно ![]() Итак , уважаемый Mayk, Вы можете пояснить в чем ненадежность данного кода?
Теперь и немного перепишем его, например , воспользуясь auto_ptr. Хотя нет, auto_ptr в данном случае не совсем уместен. Поэтому мы воспользуемся своим. Возможно класса этот немного некорректен, но для демонстрации сойдет
Уверяю Вас, что и в первом и во втором случае код "абсолютно" надежен, несмотря на то что в том и другом случае используются new[] и delete[], написанные ручками , но я, пожалуй, соглашусь, что во втором случае он оказался немного "совершенней" что ли. И если и тот и другой мне попадут на code review я приемлю с удовлетворением и ту и другую версию. Единственное, что я не приемлю, так это наличие "несовершенного кода" с наличем memory leak'ов. И дело тут не в совершенстве, или несовершестве, а банальной ошибке.
Наличие memory leak'ов свидельствует не о том, что код не является совершенным, а том что он написан с ошибками ![]() И будьте уверены, программисту на это будет указано.
Ну знаете, а чего же нарываетесь ![]() ![]() |
Автор: archimed7592 4.5.2007, 14:20 | ||||
Anikmar, ни один менеджер памяти не рассчитан на такое... специально для этих целей придуманы boost::pool, boost::object_pool, Loki::SmallObj, etc. Vyacheslav, волшебные контейнеры и смартпоинтеры как правило имеют automatic storage duration и потому автоматически освобождают память как только объект больше не нужен... Добавлено через 8 минут и 51 секунду
Добавлено через 11 минут и 55 секунд проглядел... нужно new char [1000] |
Автор: Anikmar 4.5.2007, 14:38 | ||
Это понятно, если конечно приведенные контейнеры реализовывают это не через те же new и delete. Просто vector, например, тут не поможет точно - я смотрел, там все через new и delete сделано, поэтому проблему фрагментации он не снимет. По поводу приведенных классов - ничего не могу сказать, не знаю. Там проблему пришлось решать на сколько я помню именно через свой менеджер памяти. |
Автор: Vyacheslav 4.5.2007, 15:03 | ||||
Естественно ![]() Имелось в виду
по аналогии с первым вариантом |
Автор: archimed7592 4.5.2007, 15:12 | ||
второй вариант - подменить аллокатор... например на boost::pool_aloc Добавлено через 2 минуты и 17 секунд Vyacheslav, и тем не менее... кривость рук в boost исправляется наличием разных смартпоинтеров для разных случаев (new vs new[]) ;) |
Автор: Gelos 5.5.2007, 22:47 |
Мда, дискуссия разрослась. Вобщем, немного поясню суть. Как, где-то было выше сказанно, выделялось постоянно в цикле большое колличество блоков памяти. Очень большое. То есть, в файле было около 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 6.5.2007, 20:34 | ||
Все таки останусь при своем мнении: "кривость рук" этим не исправляется, а маскируется. Если Вы не научитесь грамотно писать код, то всякие ссылки типа: "А мне это делать не привык,потому, как за меня это буст делает" вряд ли будут приняты в качестве аргумента в серьезной компании Добавлено через 6 минут и 37 секунд Вообще в своей схеме Вы не указали самый главный момент: где производился выход из бесконечного цикла?. Судя по
явно до вызов последнего вызова delete. Отсюда и утечка |
Автор: archimed7592 6.5.2007, 20:48 | ||
Vyacheslav, зачем делать класс, который можно будет использовать неправильно, когда можно сделать два класса, которые как не крути - неправильно не поюзаешь... тем более, что в с++ это решается оч простым путём стратегий и два класса делать и не придётся:
что же касается никто не спорит - во-первых, делать нужно уметь делать и так и эдак, во-вторых, привычка пользоваться мощными библиотеками не освобождает от надобности знания как эти библиотеки реализованны... а вот знание внутреннего устройства библиотеки - аргумент уже намного более серьёзный |
Автор: Earnest 7.5.2007, 11:10 | ||
Я бы не сказала, что Mayk именно такую позицию защищает. Скорее, это твоя интерпретация его постов. А его проффесионализм и знание C++ у меня сомнений не вызывает. Все, что я видела - это ратование за использование конструкций, облегчающих жизнь программистаи делающих C++ более безопасным. Лично я это тоже приветствую, и сама по другому давно не пишу (т.е. не помню, когда последний раз явно писала delete). Но у меня тоже есть ощущение, что такого рода конструкции скорее помешают начинающему программисту разобраться в языке, чем помогут. В том смысле, что у него просто не будет суровой необходимости, а любопытства может не хватить. Это немного оффтоп, но по моему опыту, программисты, пришедшие из C, лучше въезжают и больше понимают, чем программисты, пришедшие из более высокоуровневых языков типа Жавы. С другой стороны, если в проекте принято использование умных примочек (а я по опыту знаю, насколько это сокращает число потенциальных ошибок), то разрешать кому-то в целях обучения использовать голые new-delete я не собираюсь... |
Автор: Gelos 7.5.2007, 16:16 |
Vyacheslav, Хм, а знаете, может быть и так, хотя, по идее, выход у меня тогда, когда файл закончится. Может там и реально в самом конце выход случается раньше чем остатки выделенной памяти будут скормлены Ктулху... |
Автор: Vyacheslav 9.5.2007, 22:19 | ||||||||||||
Извините, но не стоит придираться к классу, который был написан на коленке для исключительно конкретной демонстрации, причем посредством отнаследования от auto_ptr ![]() ![]()
Мда ? Ну в таком случве исходя из этого совета
Вы не просветите меня , в чем заключается ненадежность new[]/delete[]. А то я их использую, а вдруг мой код из-за них ненадежен? Нехорошо как то получается ![]() Вообще в таком случае "ненадежность" new[]/delete[] я предлагаю решить кардинальным способом: мигрировать на С# ну или в крайнем случае на managed C++. Как Вам такой совет ![]() ![]()
А я не мешаю использовать их другим во вполне серьезных проектах. И не уверен, что отсутствие прямого вызова new-delete - признак ученического проекта. Не барское дело ломать стиль программирования своего подчиненного через коленку, даже если и имеешь на это право. Со временем тот и сам поймет, как улучшить свой код. Если программист что-то применяет, то он должен применять это осознанно и по делу, а не потому что без этого он не способен написать грамотный код или потому что начальник сказал, что вот это круто. И кстати , мой Вам респект. Как Вам удается найти на работу столь профессиональный контингент, которые совершенно не требуют обучения? Меня на фирме привлекают очень часто в качестве технического интервьюера при приеме кандидатов и искренне рад, когда из 5 человек хотя бы 1 показывает приемлимый уровень знаний С++ в объеме, ограниченным книгой Страутрупа первого издания.
![]() Ну и возвращаясь к нашей ситуации, когда человек спрашивает, почему у него происходят утечки и получает в ответ
выглядит весьма странно. Я не собираюсь оценивать профессионализм отвечающего, но от совета попахивает немного ламерством Вообще то, задав вопрос
я ожидал, что Mayk уточнит понятие "ненадежности" примерно так, как это сделал Anikmar и статус-кво злосчастных new[]/delete[] и языка С++ в целом было бы восстановлено. Но уважаемый Mayk упорно стал защищать свою первоначальную формулировку, присовокупив к компании ненадежных еще vector ![]() PS Gelos , прошу ни в коем случае не принимать данную дискуссию на свой счет. Это чисто теоретический спор. |
Автор: skyboy 9.5.2007, 23:01 |
выдержка из книги "Наука отладки": http://217.16.26.161/programming/digest/scofdebug/index.shtml Это к тому, что не стоит настоятельную рекомендацию "более безопасных" конструкций воспринимать как потакание ламеризму и личную обиду ![]() ![]() |
Автор: v_nikolaev 10.5.2007, 12:21 | ||
тут, наверное, следует говорить о фрагментации вместе с утечками утечки памяти могут её усугублять: пусть у нас хороший менеджкр хипа, который возвразщает операционке свободный непрерывный участок в конце своей памяти, но всё равно неподчищенная память мешает этому - на следующей фазе программа будет выделять опять то, что было невычищено - это усилит фрагментацию определённым образом. потом мы захотим выделять большие массивы, получится, что у нас нет возможности переиспользовать то, что зарезервировано. я имел дело с прогой в VC, в которой сложилась такая ситуация - из-за невычищенного мегабайта выделялись новые 400M. это также сопровождалось интересным эффектом - d-версия работала быстрее release ![]() но, возможно, дело совсем не в утечках. ещё одна проблема - возможно менеджер хипа не объединяет свободные участки, начинают алокироваться структуры данных большего размера, и переиспользовать память не удаётся. |
Автор: Earnest 10.5.2007, 13:15 | ||||||
А мне и не удается... Я их учу... А потом они сбегают в Москву, на ЗП, которую наша контора платить не может... :(
Да, всегда, если именно контейнер владеет объектами, а не просто хранит ссылки на объекты, живущие в другом месте. Основание: да хотя бы применение удаляющих алгоритмов, типа remove_if. Где потом концы искать, если это динамические указатели? Ваш функтор решит проблему только удаления на деструкторе (и в тех местах, где его можно явно включить - и еще не забыть надо это сделать). Даже если я заранее не уверена, что буду применять алгоритмы, которые могут дублировать или удалять объекты, я все равно предпочитаю безопасные контейнеры, т.к. это проще, чем ломать себе голову, думая о последствиях. Более того, если объекты не полиморфные, я предпочитаю хранить в контейнере именно объекты, а не указатели, и черт с ним, с лишним копированием. Все это позволяет сосредоточиться на алгоритме и логике. Раньше я напрягалась по поводу "лишних" действий, которые придется выполнять бедной железке. И сейчас иногда жаба душит. Но практика показывает, что реальные тормоза возникают вовсе не из-за такой фигни, а скорее из-за плохого, слишком тупого, алгоритма. А чем сложнее алгоритм, тем "самостоятельнее" должны быть данные.
Пока он будет сам это понимать, пользователи будут присылать сообщения об ошибке: "ваша программа попросила послать разработчику..." Если трепетно относиться к такому стилю, так что же тогда сказать о манере называть переменные и расставлять скобки? Свов код пусть пишет как хочет (у себя дома), а код в проекте не его, а общий. И, скорее всего, поддерживаться будет совсем другими людьми. А насчет Mayk'а, давай не будем его обсуждать: сам он к спору интерес явно потерял. |
Автор: Vyacheslav 10.5.2007, 13:44 | ||||||
Это как раз определяется внутрикорпоративным стандартом кодирования ![]() ![]()
Это как раз из другой оперы. И какже быть с циклом разработки. в который неотъемлимой частью входит тестирование?
Забыть можно все что угодно, например тот же кошелек дома. Но это еще не повод, чтобы с вечера писать у себя на лбу : "Не забыть взять кошелек " ![]() |
Автор: Earnest 11.5.2007, 17:27 | ||||
Забыть - это только одна сторона проблемы. Согласна, не забывай и все будет хорошо. Но ты ловко обошел более важную часть: что делать там, куда ручки програмиста просто не дотянутся, например, повторю, при применении алгоритмов типа revove_if. Там хорошая память не спасет. Кроме того, если мы беремся корректировать чужой код, про это надо еще и узнать как-то.
Ну хорошо, насчет пользователей я погорячилась, но тестеры тоже люди... Да и самого программиста жалко (в смысле, его зарплату, которая платится за то время, пока он ищет дурацкие ошибки, которых могло бы и не быть). Но самое главное тем не менее не это. Все эти умные примочки эфективно сокращают количество написанного руками кода. Это я не к тому, что стучать по клавишам лень. А к тому, что лишние технические детали загромождают алгоритм и скрывают его логику. Конечно, структурировать код можно хорошо и без умных примочек, только усилий нужно приложить больше. А, спрашивается, ради чего? Если есть известные способы избежать лишних траблов?
Этот аргумент не кажется мне, мягко говоря, убедительным. Разве это означает, что эта практика плоха? И в чем, в конце концов, проблема? Ну пусть конкретный программист пока не знает о RAII. Ну так я расскажу и покажу. А потом попрошу переписать его код. Если код изначально хорош, это совсем нетрудно. |
Автор: Vyacheslav 12.5.2007, 19:10 | ||||||||||
Но Вы тоже ловко обошли вопрос: ведь не всегда легко можно заменить указатели на сами объекты ![]() ![]() примерно так
Надеюсь данный пример достаточно презентативен ![]()
Вы все меня стараетесь убедить, что эти "умные примочки" благо? Это напрасный труд ![]()
Мне кажется я уперся в стену ![]()
Да проблемы нет. Но если код "изначально хорош", чего его трогать. А рассказать и показать можно. А насчет переписать, не знаю. Если код удовлетворяет требуемому уровню безопасности и не имеет дефектов, то смысл его переписывать? Не лучше ли дать следущее задание, в котором он сможет применить полученные знания. |
Автор: Earnest 13.5.2007, 08:09 | ||
ОК, значит мы во всем согласны. От кривых рук или ошибки в ДНК это действительно не спасает. Насчет помочь разобраться... В принципе, конечно, правильно ты говоришь, но только теоретически. Некоторый начальный уровень должен быть достигнут самостоятельно, иначе на что это программист годится? А многие начинающие программисты нынче так обленились со всеми этими супер-средами, где все "само" делается, что все им в рот положи, да и разжуй еще, а они только стонут - ох, как неудобно и непонятно.... Поэтому и возникают отписки типа - используй STL и т.д. |