Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Мифы о плюсах |
Автор: ТарасАтавин 7.10.2013, 11:22 | ||
Миф № 1. Указатели страдают опасностью утечки, якобы забывается delete и поэтому нужен сборщик мусора, который всё адалит автоматически. Я программирую с 1995-го, а конкретно на плюсах с 2001-го. Потратил больше месяца, чтоб добиться утечки. Думаете, я delete забыл? Чёрта с два, он набирается инстинктивно с того самого 2001-го с первого дня использования плюсов и до сих пор. А пропустил я присвоить указатель при увеличении массива. Внимание вопрос: чем мне поможет сборщик? Он ведь не знает, что нужно удалить и нужно ли что то вообще удалять, а чтоб понять это из текста, надо его анализировать, имея знания и подлинный разум, не уступающие автору. В примере с пропущенным присваиванием
|
Автор: Amp 7.10.2013, 13:16 |
Прилетит исключение, что будешь делать? |
Автор: ТарасАтавин 7.10.2013, 13:16 |
Миф и заключается именно в том, что он нужен только для этого, проблему гарантированно решает, а без него она не решаема. |
Автор: Static 7.10.2013, 13:17 |
Миф №2: Люди, которые "программируют на плюсах" более 10 лет, досконально хорошо знают язык программирования С++. |
Автор: Alexeis 7.10.2013, 13:47 |
Язык С++ ориентирован на статические конструкции (шаблоны, объекты поля, структуры). Статическое связывание и т.д. Пока это так операций new/delete не так много и можно избежать утечек. Другое дело ситуации, когда на этапе компиляции есть мало информации о структурах данных, когда все это саморазварачивается, связывается, подгружается и т.д. Появляются ситуации когда время жизни объекта неизвестно и зависит от состояния других объектов. А если еще это все запущено в многопоточной среде, то следить становиться совсем сложно. В примитивных случаях конечно нет проблем отследить выделение/освобождение. Зачастую даже этого делать даже не нужно. В STLе полно контейнеров которые сами за всем следят. |
Автор: ТарасАтавин 7.10.2013, 15:08 | ||||||||
Добавлено через 4 минуты и 28 секунд
Добавлено через 5 минут и 29 секунд
Добавлено через 7 минут и 18 секунд
|
Автор: Static 7.10.2013, 15:35 | ||||||
Здравый смысл подсказывает, что речь идет о случаях, когда созданный объект "отправляется в самостоятельное плавание" и, таким образом, время его жизни не контролируется кодом, который его создал. А вовсе не о том, что ты заранее не знаешь, сколько точно времени проживет некий объект.
Примерно так же, как и все остальное. Она не связана с потоками, но многопоточность требует особого подхода, в том числе и к выделению/освобождению памяти.
А об использовании указателей Вы же сами разговор и начали. А намек на контейнеры STL почему-то проигнорировали. Человек, который может разговаривать в таком тоне, должен быть способен решать свои проблемы с ЯП самостоятельно, без создания тысяч тем об очевидных и банальных, в общем-то, вещах. |
Автор: ТарасАтавин 7.10.2013, 15:39 | ||||
И загоняют в рамки. А я вот не хочу stlовый вектор, я хочу строго квадратный массив деревьев списков графорв общего вида? Или дерево на 9-ти взаимоортогональных парах левый-правый потомок? Или ещё что нибудь такое, что разработчки stl могли не предусмотреть. Документ должен сам содержать каталоги, но не быть архивом абстрактных файлов? И в этом внутреннем графе каталогов нет понятия ярлыка, но есть понятие "альтернатива" и альтернатива есть второй путь к каталогу/элменту, то есть был некоторый элемент документа, потом в другом каталоге создана его альтернатива, доступ через эту альтернативу есть доступ к самому элементу, как по ярлыку, то есть любое изменение о отразится на самом элементе и его будет видно, если в следующий раз открыть этот же элемент не через альтернативу, но в отличие от ярлыка, удаление самого элемента не означает удаления данных, пока у этого элемента есть хоть одна альтернатива? Да мало ли что я могу придумать. Так вот, даже если разработчики stl угадают и все мои идеи, и всё, что в бреду изобретёт горе-студент, проще будет историку самостоятельно и без утечек реализовать свой контейнер, чем самому страуструпу изучить на столько универсальную супербиблиотеку контейнерных классов, а при её использовании избежать краха по каким нибудь другим, не связанным с утечками, причинам. Одно дело строки, они достаточно стандартны и ничего нового в плане интерфейса для них не придумаешь, поэтому std::string и ни каких гвоздёв. В крайнем случае версия на другой кодировке, например, на равномерном юникоде. Или на utf-8. На utf-16. На dos-кодировке вместо ANSI. На чём угодно, но сам контейнер остаётся тем же. И совсем другое дело все остальные контейнеры, даже динамические массивы. Один хочет хранить всё, а при добавлении нового индекса добавлять элемент, другому подавай разреженный массив, хеш-функцию из целочисленного деления и прямое отождествление соседних элементов друг с другом, третьему нужно исключение при попытке обратиться по несуществующему действительному индексу, у четвёртого индекс есть октодерево, пятый заводит списки коллизий в разреженном массиве, шестому подавай аппроксимацию не существующих элементов полиномом сотого порядка и всё называется одинаково и даже имеет общую декларацию интерфейса. Добавлено через 1 минуту и 6 секунд
Добавлено через 8 минут и 36 секунд Да. Но нужны они не в
|
Автор: Static 7.10.2013, 15:50 | ||
В таком случае я не понимаю, чем вызван вопрос о времени жизни. Вы за свои 18 лет работы с кодом не встречали подобных ситуаций? Добавлено через 1 минуту и 19 секунд Будем честны - там и с++ не нужен-то. |
Автор: ТарасАтавин 7.10.2013, 15:51 | ||||
Добавлено через 1 минуту и 59 секунд
|
Автор: Static 7.10.2013, 16:07 |
Я ценю Ваши образные и красивые аналогии, но почему Вы отвечаете не на то, что цитируете? Я написал про выделение/освобождение памяти - Вы мне про указатели. И не поспоришь, да, на указатели как на таковые многопоточность действительно не влияет. А когда Вам понадобится выделять память в одном потоке, освобождать в другом - вот тогда все будет намного интереснее. И простите мне этот шаг в сторону, но Вы свои мифы сами придумываете, а потом проецируете их на всех. Я помню, что где-то уже сталкивался с чем-то подобным. И точно - http://www.gamedev.ru/flame/forum/?id=160639&page=4#m59. И что-то с того времени прогресс сомнителен. |
Автор: ТарасАтавин 7.10.2013, 18:13 | ||
Добавлено @ 18:16 А ничего, что эту тему именно я поднял не там, а здесь? Там же я отвечал. Рассказывается же миф сторонниками c#, которых я обзываю зарешёченными. Ищи на геймдеве мой пост про тюрьму разума мелкософт. |
Автор: bsa 11.10.2013, 00:23 | ||||||||||
Это называется ссылка. Бывают жесткие ссылки (в большинстве ФС каталоги . и .. - это жесткие ссылки соответственно на текущий каталог и на родительский) и символические - специальный файл, который содержит относительный или абсолютный путь к фактическому файлу. В твоем случае это жесткая ссылка. Удаление файла происходит при удалении всех ссылок на него. Не надо придумывать новую терминологию. Эта задача решается с помощью нескольких примитивных структур (нода, файл и каталог), std::list и std::shared_ptr. Изобретать свои контейнеры нет смысла.
![]()
![]()
Эх, почему люди, которые ничего не знают и знать не хотят, так настойчиво пытаются навязывать свое мнение другим. |
Автор: boostcoder 21.10.2013, 20:15 |
GC нужен для...ээмм.. хз для чего, правда. в С++ есть отличная идиома - RAII. зы немного оффтоп, но думаю многим пригодится. есть проект, довольно таки большой проект, ~150000 loc. начали подготавливать проект к релизу, и обнаружились "стандартные" Си`шные чудеса в виде произвольных падений программы. при том валилась программа в совершенно разных участках, порою даже не связанных(разве что адресным пространством). я в течении нескольких дней понял, что мы имеем дело либо с порчей кучи/стека, либо с висячими указателями, либо и то, и другое. и вот, три человека, в течении месяца, полный рабочий день занимаются только поисками этих багов. по истечении месяца стало понятно, что ничего найти не получается. стандартные средства типа отладчика и стек-трейсера никак не помогают, а только путают. так же опробован valgrind, который, к слову, тоже только "голову морочил". не для плюсового кода он, однако. и вот, как последняя надежда, решили попробовать https://code.google.com/p/address-sanitizer/, который был включен в gcc-4.8.х(так же был добавлен и https://code.google.com/p/thread-sanitizer/, но его пока не приходилось опробовать), и, с его помощью, за один день пофиксили баги. баги, как оказалось, были однотипные, и всего три - висячие указатели ![]() хз, сколько еще месяцев потребовалось бы на поиски этих багов, без asan %) вот такая вот история. но даже в этой ситуации я не думаю, что в С++ нужен GC. тут виноваты исключительно кривые руки ;) |
Автор: vinter 21.10.2013, 20:22 | ||
GC в C++ нужен для эффективной реализации некоторых алгоритмов. Каких? Не имею понятия, об этом говорил Саттер, в одном из видео. |
Автор: bsa 21.10.2013, 23:29 | ||
![]() Он ругается на некоторые внешние библиотеки, например OpenGL и OpenSSL. Чтобы с последним проблем не было, нужно пересобрать OpenSSL с ключиком -DPURIFY. А все остальное можно решить через списки исключений. |
Автор: boostcoder 22.10.2013, 01:41 |
ни OpenGL ни OpenSSL в проекте не используются. по правде сказать, я устал заполнять этот список. валгринд ругался на многое... на смарт указатели, на std/boost bind, на boost::intrusive, на boost::interprocess, на boost::multi_index, и на много чего другого... особенно весело было с лямбдами. он ругался на каждую лямбду которая захватывала this, или любой другой указатель. при этом, в список ислючения приходилось вносить каждую лямбду, которых в проекте наверное тысячи %) при этом, его перлы были размером в несколько мегабайт, в первые несколько секунд работы программы. а с AddressSanitizer все гладко - никакого лишнего вывода, все только по существу, и не разу не ошибся ;) |
Автор: azesmcar 22.10.2013, 10:08 |
На тему http://herbsutter.com/2011/10/25/garbage-collection-synopsis-and-c/ |
Автор: Dem_max 23.10.2013, 04:14 | ||
делаете new для одной переменой Data=new TItem [Count]; А delete делаете для другой переменной delete []this->Data; Я наверное поддержу.
|
Автор: ТарасАтавин 23.11.2013, 13:46 | ||
Добавлено @ 13:48 А как ещё? Data - новый блок, this->Data - старый. Один выделяется, другой освобождается. Просто пропущено присваивание this->Data=Data до завершения. |
Автор: Alexeis 23.11.2013, 17:53 | ||
Люди не роботы, во время работы отвлекаются переключаются на что-то, пишется некоторый код, потом через месяц переделывается и т.д. В таких условиях утечки делаются очень легко, а бывает, что повторное удаление указателей. |
Автор: ТарасАтавин 24.11.2013, 16:09 | ||
Добавлено через 5 минут и 46 секунд Ну вернулся ты через год к старому исходнику. И что? Добавишь new, а delete оставишь ещё на год? А может ещё после каждого движения мыши, щелчка, даблокликА, нажатия на кею, или отпускания её до следующего события месяца полтора проходит? В таком режиме вообще не возможно что либо сделать, а в нормально сразу и new, и парный delete набираются за несколько секунд и по одному решению, что исключает утечки. Единственный возможный их источник - пропуск присваивания, который ни каким инструментом не отловишь, их только на основе замысла. |
Автор: Amp 24.11.2013, 18:27 |
Ты действительно считаешь, что new и парный delete спасет от утечек? Или просто прикидываешься? |
Автор: ТарасАтавин 25.11.2013, 08:57 | ||||
|
Автор: NoviceF 25.11.2013, 09:13 | ||
То, что пришло в голову. |
Автор: baldina 25.11.2013, 10:16 |
он не прикидывается, у него 10 лет программирования за плечами ![]() |
Автор: ТарасАтавин 25.11.2013, 15:56 |
Что за фигня? delete должен быть до завершения, иначе пара разбита. |
Автор: NoviceF 25.11.2013, 16:13 | ||
А.. тебя только это место смутило? ![]() |
Автор: boostcoder 7.12.2013, 00:12 |
а не нужно быть роботом, достаточно использовать прямые идиомы. |