Какова философия управления памятью на С++?

Извините за большой объем вопросов. Но каков фактор проектирования при управлении памятью на С++? Например: почему происходит утечка памяти, когда программа не освобождает объект памяти до ее выхода? Разве это не хороший дизайн языка программирования, который должен поддерживать "foo-table", который заботится об этой ситуации? Я знаю, что я немного наивна, но что такое философия дизайна управления памятью в С++ в отношении классов, структур, методов, интерфейсов, абстрактных классов?

Конечно, нельзя гуманно помнить каждую спецификацию С++. Какова основная концепция управления памятью?

Ответ 1

Какова основная концепция управления памятью?

Почти во всех случаях вы должны использовать автоматическое управление ресурсами. В основном:

  • Где бы это ни было целесообразно, предпочитайте создавать объекты с автоматическим временем хранения (то есть в стеке или в функции-локальном)
  • Всякий раз, когда вы должны использовать динамическое распределение, используйте ограниченное областью управление ресурсами (SBRM, более часто называемое Инициализация ресурсов - это Инициализация или RAII).

Редко вам приходится писать свой собственный контейнер RAII: стандартная библиотека С++ предоставляет целый набор контейнеров (например, vector и map) и интеллектуальные указатели, такие как shared_ptr (из С++ TR1, С++ 0x и Boost) работают очень хорошо для большинства распространенных ситуаций.

В принципе, в действительно хорошем коде на С++ вы никогда не должны вызывать delete самостоятельно 1 для очистки выделенной памяти: управление памятью и очистка ресурсов всегда должны быть инкапсулированы в контейнер какой-то.

1. Очевидно, что здесь возникает исключение, когда вы сами реализуете контейнер RAII, поскольку этот контейнер должен отвечать за очистку того, что принадлежит ему.

Ответ 2

Не совсем понятно, спрашиваете ли вы о философии того, что встроено в С++, или о том, как использовать его таким образом, чтобы предотвратить утечку памяти.

Основной способ предотвращения утечек памяти (и других утечек ресурсов) известен как RAII (инициализация получения ресурсов) или SBRM (управление ресурсами с ограниченным диапазоном). В любом случае основная идея довольно проста: поскольку объекты с длиной auto хранения автоматически уничтожаются при выходе из своей области, вы выделяете память в ctor такого объекта и освобождаете память в своем dtor.

Что касается самого С++, у него действительно нет философии. Он предоставляет механизмы, но оставляет программисту возможность решить, какой механизм подходит для данной ситуации. Это часто RAII. Иногда это может быть сборщик мусора. В других случаях, в других случаях это могут быть разные типы пользовательских менеджеров памяти. Конечно, иногда это комбинация двух или всех трех из них или чего-то еще.

Изменить: Что касается того, почему С++ делает это так, это довольно просто: практически любой другой вариант сделает язык неподходящим по крайней мере для некоторых видов проблем, включая число, для которого С++ явно был предназначен для использования. Одним из наиболее очевидных из них является возможность запуска на "голой" машине с минимальной структурой поддержки (например, без ОС).

Ответ 3

C и С++ согласны с тем, что вы, программист, знаете, когда закончите с выделенной вами памятью. Это позволяет избежать необходимости в том, чтобы языковая среда выполнения знала многое о том, что было выделено, и связанные задачи (подсчет ссылок, сбор мусора и т.д.), Необходимые для "очистки", когда это необходимо.

В сущности идея состоит в том, что: если вы ее выделите, вы должны освободить ее. (malloc/free, new/delete)

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

Ответ 4

почему возникает утечка памяти, когда программа не освобождает объект памяти до ее выхода?

Ну, ОС обычно очищает ваш беспорядок для вас. Однако, что происходит, когда ваша программа работает в течение произвольного промежутка времени, и вы пропустили столько памяти, которую больше не можете выделить? Вы рухнете, и это не хорошо.

Не хороший дизайн языка программирования, который должен поддерживать "foo-table", который заботится об этой ситуации?

Нет. Некоторые языки программирования имеют автоматическое управление памятью, некоторые - нет. Для обеих моделей есть преимущества и недостатки. Языки с ручным управлением памятью позволяют говорить, когда и где ресурсы выделяются и выпускаются, т.е. Они очень детерминированы. Относительный новичок, однако, неизбежно напишет код, который течет, когда они привыкнут к управлению памятью.

Автоматизированные схемы отлично подходят для программиста, но вы не получаете такого же уровня детерминизма. Если я пишу аппаратный драйвер, это не может быть хорошей моделью для меня. Если бы я писал простой графический интерфейс, то, вероятно, мне все равно, что некоторые объекты сохраняются дольше, чем нужно, поэтому я буду использовать автоматическую схему управления каждый раз. Это не означает, что языки GC'd предназначены только для "простых" задач, некоторые задачи требуют более жесткого контроля над вашими ресурсами. Не все платформы имеют 4 ГБ + память для вас, чтобы играть в).

Существуют шаблоны, которые вы можете использовать для управления памятью. Канонический пример: RAII (Инициализация ресурсов)

Ответ 5

Философия - я думаю, что есть две вещи, которые приводят к тому, что С++ не имеет сборщика мусора (который, похоже, вы получаете):

  • Совместимость с C. С++ пытается быть очень совместимой с C, лучше или хуже. C не было сбора мусора, поэтому С++ не работает, по крайней мере, не по умолчанию. Думаю, вы могли бы подвести итог как "исторические причины".

  • "Вы платите только за то, что используете". С++ пытается избежать накладных расходов выше C, если вы явно не попросите об этом. Таким образом, вы платите только стоимость исключений, если вы на самом деле бросаете один и т.д. Существует аргумент, что сбор мусора будет налагать стоимость всякий раз, когда объект распределяется по куче, поэтому он не может быть по умолчанию в С++.

    Обратите внимание, что на самом деле довольно много дискуссий о том, действительно ли сбор мусора более или менее эффективен, чем ручное управление памятью. Лучшие сборщики мусора, как правило, хотят иметь возможность перемещать вещи, хотя, и С++ имеет арифметику указателя (опять же, унаследованную от C), что очень затрудняет работу такого коллектора с С++.

Здесь Stroustrup (на самом деле не прямой) ответ на " Почему С++ не имеет сборку мусора?":

Если вы хотите автоматическую сборку мусора, есть хорошие коммерческие сборщики мусора для публичного домена для С++. Для приложений, в которых сбор мусора подходит, С++ - превосходный сборник мусора, который отличается выгодным соотношением с другими языками, собранными с мусором. См. Язык программирования С++ (3-е издание) для обсуждения автоматической сборки мусора на С++. См. Также, Ханс-Дж. Сайт Boehm для сбора мусора C и С++.

Кроме того, С++ поддерживает методы программирования, которые позволяют управлять памятью безопасно и неявно без сборщика мусора.

С++ 0x предлагает GC ABI.

Ответ 6

Не хороший дизайн языка программирования, который должен поддерживать "foo-table", который заботится об этой ситуации?

Это? Зачем? Хороший язык программирования - это тот, который позволяет решать проблемы, не более, не меньше. Сборщик мусора, безусловно, снижает барьер входа, но он также берет контроль над программистом, что может быть проблемой в некоторых случаях. Правда, на современном четырехъядерном процессоре с частотой 2,5 ГГц, а также с сегодняшними передовыми и эффективными сборщиками мусора мы можем с этим справиться. Но С++ пришлось работать с гораздо более ограниченным оборудованием, начиная от настольных компьютеров с колоссальным 16 МБ оперативной памяти и заканчивая встроенными платформами с 16 КБ и все между ними. Он должен использоваться в реальном времени, где вы не можете просто приостановить программу на 0,5 секунды, чтобы запустить сборку мусора.

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

Руководящий принцип С++ - "вы не платите за то, что не используете". Если вы не хотите сборщика мусора, вам не придется платить (крутую) цену за один.

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

Ответ 7

Какова основная концепция управления памятью?

Конструкция вождения (не предназначенная для каламбура) немного похожа на конструкцию автомобилей с коробкой передач с коробкой передач, в отличие от автомобилей с автоматической коробкой передач. Как машина смены пальцев, С++ дает вам свободу и контроль над машиной, но она не так проста в использовании, как автоматические, которые заботятся о многом для вас.

В С++ и Java можно было легко написать следующее:

Люди, которые управляют автомобилями смены палок, знают разницу и преимущества имея полный контроль над вашим двигателем автомобиля; люди, которые управляют автомобилями с автоматическим передач нет. (...) Гоночные автомобили, например, не используют автоматические трансмиссий. (...) Люди, привыкшие к переключению передач, будут больше сосредоточены на их вождении, делая его более эффективным и безопасным.

http://www.eslbee.com/contrast_stick_shift_or_automatic.htm

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

Ответ 8

С++ не имеет философии дизайна по памяти. Все, что у него есть, это две функции для выделения памяти (новый malloc) и две функции для освобождения памяти (удалить бесплатно) и связанные с frew функциями. Даже те, которые могут быть заменены программистом.

Это связано с тем, что С++ предназначен для работы на общих компьютерах. Общие компьютеры - это CPU, память (RAM, разновидности ROM) и шины/шины для периферийных устройств. На общих компьютерах нет встроенного управления памятью.

Теперь большинство компьютеров имеют память (как правило, вариант с ПЗУ), который содержит биос/монитор. Там вы можете увидеть некоторую рудиментарную форму управления памятью - возможно, нет.

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

Если вы ожидаете, что С++ будет запущен на любом компьютере, у него не может быть философии управления памятью.