Люди, которые привыкли собирать языки, часто боятся управления памятью в C ++. Существуют такие инструменты, как auto_ptr
и shared_ptr
которые будут выполнять многие задачи по управлению памятью для вас. Множество библиотек C ++ предшествуют этим инструментам и имеют собственный способ обработки задач управления памятью.
Сколько времени вы тратите на задачи управления памятью?
Я подозреваю, что это сильно зависит от набора библиотек, которые вы используете, поэтому, пожалуйста, скажите, к каким из них относится ваш ответ, и делают ли они это лучше или хуже.
Ответы:
Современный C ++ заставляет вас не беспокоиться об управлении памятью до тех пор, пока вам не потребуется, то есть до тех пор, пока вам не понадобится организовать свою память вручную, в основном для целей оптимизации или если контекст заставляет вас это делать (подумайте об аппаратных средствах с большими ограничениями). Я писал целые игры, не манипулируя необработанной памятью, только опасаясь использования контейнеров, которые являются подходящим инструментом для работы, как на любом языке.
Так что это зависит от проекта, но большую часть времени вам приходится управлять не памятью, а только временем жизни объекта. Это решается с помощью умных указателей , которые являются одним из идиоматических инструментов C ++, полученных в результате RAII .
Как только вы поймете RAII , управление памятью не будет проблемой.
Затем, когда вам понадобится доступ к необработанной памяти, вы сделаете это в очень конкретном, локализованном и идентифицируемом коде, как в реализациях объектов пула, а не «везде».
Вне этого вида кода вам не нужно манипулировать памятью, только время жизни объектов.
Самое сложное - это понять RAII.
источник
delete
вручную, если у вас нет одной хреновой реализации.return
)Управление памятью используется, чтобы напугать детей, но это всего лишь один из видов ресурсов, за которыми должен следить программист. Подумайте о дескрипторах файлов, сетевых подключениях, других ресурсах, которые вы получаете из ОС.
Языки, которые поддерживают сборку мусора, обычно не только игнорируют существование этих ресурсов, но и затрудняют их правильную обработку, не предоставляя деструктора.
Итак, короче говоря, я бы предположил, что не так много времени разработчика C ++ тратится на заботу об управлении памятью. Как показывает ответ Клаима , как только вы получите дескриптор RAII, все остальное просто рефлекс.
источник
finalize
конструкция. Однако вы не знаете, когда он будет вызван. Будет ли это до того, как у вас закончатся сокеты или объекты WebResponse? Вы найдете множество статей, которые говорят вам, что вы не должны полагатьсяfinalize
- и на то есть веская причина.Почти нет. Даже в старых технологиях, таких как COM, вы можете написать собственные средства удаления для стандартных указателей, которые преобразуют их за очень короткое время. Например,
std::unique_ptr
может быть преобразован в уникальную ссылку COM с пятью строками пользовательского удалителя. Даже если вам придется вручную писать собственный обработчик ресурсов, распространенность таких знаний, как SRP и копирование-и-своп, позволяет относительно легко написать класс управления ресурсами, который будет использоваться вечно.Реальность такова, что совместно используемый, уникальный и не принадлежащий владельцу все поставляется вместе с вашим компилятором C ++ 11, и вам просто нужно написать небольшие адаптеры, чтобы они работали даже со старым кодом.
источник
Когда я был программистом на C ++ (давным-давно), я очень долго беспокоился об ошибке управления памятью, пытаясь исправить ошибки, чтобы воспроизвести ошибки .
С модемом C ++ управление памятью становится намного менее сложной задачей, но вы можете довериться всем в большой команде, чтобы сделать это правильно. Какова стоимость / время:
Так что это не просто время, затрачиваемое на « выполнение », это больше проблема крупных проектов.
источник
Я часто использую библиотеки boost и TR1, и они делают управление памятью в строгом смысле слова (new / delete) несложным. С другой стороны, выделение памяти в C ++ недешево, и нужно обратить внимание на то, где создаются эти причудливые общие указатели. Вы часто используете рабочие пространства или работаете со стековой памятью. В целом, я бы сказал, что это в основном проблема дизайна, а не проблема реализации.
источник
сколько времени это занимает в качестве клиента? очень мало, как только вы освоитесь. когда контейнер управляет временем жизни и ссылками, это действительно очень просто. imo, это намного проще, чем ручной подсчет ссылок, и он практически прозрачен, если вы рассматриваете контейнер, который вы используете, как документацию, которую компилятор удобно предотвращает от выполнения недопустимых передач прав собственности в хорошо спроектированной безопасной системе.
Большую часть времени, которое я провожу (как клиент), тратят на содержание типов из других API, поэтому они хорошо работают в контексте ваших программ. Пример: это мой ThirdPartyFont контейнер, и он поддерживает эти функции, и уничтожение орудий таким образом, и подсчет ссылок таким образом, и скопировав этот путь, и ... . Многие из этих конструкций должны быть на месте, и зачастую это логичное место для их размещения. хотите ли вы включить это как время или нет, зависит от вашего определения (реализация должна существовать при взаимодействии с этими API, в любом случае, верно?).
после этого вам нужно будет учитывать память и владение. в системе более низкого уровня это хорошо и необходимо, но может потребоваться некоторое время и леса, чтобы реализовать то, как вы должны перемещать вещи. я не вижу в этом боли, так как это требование системы более низкого уровня. собственность, контроль и ответственность очевидны.
таким образом, мы можем обратить это к API-интерфейсам на основе c, которые используют непрозрачные типы: наши контейнеры позволяют нам абстрагировать все мелкие детали реализации управления временем жизни и копированием этих непрозрачных типов, что в конечном итоге делает управление ресурсами очень очень простым и экономит время, дефекты, и уменьшает реализации.
использовать их действительно очень просто - проблема (исходящая от GC) в том, что вы должны теперь учитывать время жизни ваших ресурсов. если вы ошиблись, решение может занять много времени. Изучение и интеграция явного управления жизненным циклом по понятным причинам сложно для сравнения (не для всех людей) - это настоящее препятствие. если вам удобно управлять временем жизни и использовать хорошие решения, тогда действительно очень легко управлять временем жизни ресурса. это не значительная часть моего дня (если не закралась трудная ошибка).
если вы не используете контейнеры (автоматический / общий указатель), то вы просто умоляете о боли.
Я реализовал свои собственные библиотеки. Мне нужно время, чтобы реализовать эти вещи, но большинство людей используют их повторно (что обычно является хорошей идеей).
источник
Ты имеешь в виду, что нужно вручную освобождать память, закрывать файлы и тому подобное? Если это так, я бы сказал, минимум и, как правило, меньше, чем большинство других языков, которые я использовал, особенно если мы обобщим это не только для «управления памятью», но и «управления ресурсами». В этом смысле я на самом деле думаю, что C ++ требует меньше ручного управления ресурсами, чем, скажем, Java или C #.
Это происходит главным образом из-за деструкторов, которые автоматизируют уничтожение ресурса (памяти или иным образом). Как правило, единственный раз, когда мне нужно освободить / уничтожить ресурс вручную в C ++, это если я реализую структуру данных vlow-уровня (что большинству людей не нужно делать) или использую C API, где я просто провожу немного времени обертывание ресурса C, который необходимо вручную освободить / уничтожить / закрыть, в оболочку C ++, соответствующую RAII.
Конечно, если пользователь просит закрыть изображение в программном обеспечении для редактирования изображений, я должен удалить изображение из коллекции или что-то еще. Но, надеюсь, это не считается как управление «памятью» или «ресурсами», которое имеет значение в этом контексте, поскольку это требуется в любом языке, если вы хотите освободить память, связанную с этим образом в то время. Но опять же, все, что вам нужно сделать, это удалить изображение из коллекции, а деструктор изображения позаботится обо всем остальном.
Между тем, если сравнивать, скажем, с Java или C #, вы часто обнаруживаете, что людям приходится закрывать там файлы вручную, вручную отключать сокеты, устанавливать нулевые ссылки на объекты, чтобы их можно было собирать мусором, и т. Д. управление ресурсами на этих языках, если вы спросите меня. В C ++ вам часто даже не нужен
unlock
мьютекс вручную, так как мьютекс-локатор сделает это автоматически, когда мьютекс выйдет из области видимости. Например, вы никогда не должны делать такие вещи в C ++:Там нет необходимости делать такие вещи, как закрытие файлов вручную в C ++. В конечном итоге они автоматически закрывают себя в тот момент, когда выходят из области видимости, независимо от того, выходят ли они из области видимости в результате или нормальных или исключительных путей выполнения. Аналогичная вещь для ресурсов, связанных с памятью, как
std::vector
. Такой код, подобныйfile.Close()
приведенному выше, часто не одобряется, поскольку, особенно в контекстеfinally
блока, который предполагает, что локальный ресурс должен быть освобожден вручную, когда весь мышление вокруг C ++ должно автоматизировать это.С точки зрения ручного управления памятью, я бы сказал, что C требует максимум, Java / C # - среднее, а C ++ - минимум. Есть много причин стесняться использования C ++, так как это очень сложный язык для овладения, но управление памятью не должно быть одной из них. Наоборот, я на самом деле думаю, что это один из самых простых языков в этом аспекте.
Конечно, C ++ позволяет вам начинать выделять память вручную и вызывать ее
operator delete/delete[]
для освобождения памяти вручную. Это также позволяет вам использовать функции C, такие какmalloc
иfree
, Но это практика кодирования в древнем стиле, которая, я думаю, устарела задолго до того, как люди стали отдавать должное, поскольку Страуструп защищал RAII еще до того, как он придумал этот термин с самого начала. Так что я даже не думаю, что будет справедливо сказать, что «современный C ++» автоматизирует управление ресурсами, потому что это должно было быть целью с самого начала. В противном случае вы практически не можете получить безопасность исключений. Просто многие заблуждающиеся разработчики в начале 90-х пытались использовать C ++ как C для объектов, часто полностью игнорируя обработку исключений, и это никогда не предполагалось использовать таким образом. Если вы используете C ++ так, как его планировали использовать практически всегда, тогда управление памятью полностью автоматизировано, и, как правило, вам вообще не приходится (или нужно) иметь дело с этим вручную.источник
Зависит от старшего технического руководства в команде. В некоторых компаниях (включая мою) нет понятия «умный указатель». Это считается фантазией. Таким образом, люди просто помещают удаления повсюду, и каждые 2 месяца существует система устранения утечек памяти. Новая волна утверждений удаления прибывает всюду. Итак, зависит от компании и типа людей, которые там работают.
источник
auto_ptr
и друзей?