Вопрос по c++, c, dynamic-memory-allocation – Может ли блок памяти, выделенный с помощью оператора new / malloc, сохраняться после завершения выполнения программы? [Дубликат]

14

Possible Duplicate:
When you exit a C application, is the malloc-ed memory automatically freed?

Этот вопрос пришёл мне в голову, когда я читал о том, как принудительно использовать delete / free соответственно, когда речь идет о динамическом распределении памяти в C / C ++. Я думал, что если выделение памяти сохранится после завершения выполнения моей программы, то да, это обязательно; в противном случае, почему я должен беспокоиться об освобождении выделенного пространства? Разве ОС не собирается автоматически освобождать ее при завершении процесса? Насколько я прав? Мой вопрос в том, что может

int *ip = new int(8);

сохраняться после окончания моей программы?

Он освобождается, когда процесс завершается, но попробуйте в цикле. Superman

Ваш Ответ

9   ответов
6

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

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

Не только это, но это может бытьcrucial освободить память. Вы думаете, что клиенты / пользователи будут довольны, когда ваш демон backgrund потребляет на 500 МБ больше оперативной памяти каждый час?
Ой! Я понял Извините ... Я думал, что вы хотите выбросить указатель и позволить ОС получить его в конце. Виноват! +1!
@Linuxios Я имел в виду ситуации, когда после выделения памяти она действительно нужна вашей программе, и единственный раз, когда ваша программа может освободить эту память, это прямо перед выходом.
15

Длинный ответ: Нет. C ++ никогда не сохранит память, если вы не сделаете работу, чтобы сделать это. Причина освобождения памяти заключается в следующем:

Если вы не освобождаете память, но продолжаете ее выделять, в какой-то момент у вас закончится память. Как только вы закончите, почти все может случиться. В Linux, возможно, OOM killer активирован и ваш процесс убит. Может быть, ОС выдает страницы полностью на диск. Может быть, вы даете Windows окно синего экрана, если вы используете достаточно памяти. Это почти можно считать неопределенным поведением. Кроме того, если вы теряете память, она просто находится там, не используется, не выпущена, и никто не может использовать ее, пока ваш процесс не завершится.

Есть и другая причина. Когда вы освобождаете память для распределителя, распределитель может сохранить ее, но просто пометить как пригодную для использования. Это означает, что в следующий раз, когда вам понадобится память, она уже сидит и ждет вас. Это означает, что в ядре меньше вызовов для запроса памяти, что повышает производительность, поскольку переключение контекста очень неэффективно.

РЕДАКТИРОВАТЬ: стандарты C и C ++ даже не дают гарантии, что память будет очищена ОС после завершения. Многие операционные системы и компиляторы могут, но нет никакой гарантии. Несмотря на это, все основные настольные и мобильные операционные системы (за исключением, вероятно, DOS и некоторых очень старых встроенных систем) очищают память процессов после нее.

Этот ответ очень ориентирован на Linux. Я совсем не уверенlanguage гарантирует такое поведение.
@unwind: Нет, язык не такой. Я буду редактировать. Я знаю, что он ориентирован на Linux, но Linux это то, что я знаю.
Он не был "исправлен" потому что, по-видимому, это сломало бы комбоfork()/exec() когда родительский процесс использует много памяти:quora.com/…
@ Damon: Почему вы называете OOM убить мерзость? Когда системаtruly Недостаточно памяти (больше нет физической памяти, больше нет места подкачки), то система должнаsomethingне так ли? И почему убийство оскорбительного процесса плохо? До тех пор, пока он может быть настроен так, чтобы ваш критически важный серверный процесс не был готов к работе.
@unwind: Хотя это и правда, в других системах это не сильно отличается (за исключением, конечно, немногих систем, в первую очередь, таких мерзостей, как убийца ООМ). Это могло отличаться примерно 20 лет назад на «домашнем компьютере», но в настоящее время в каждой основной операционной системе (и в каждой профессиональной операционной системе за последние 40–45 лет), когда процесс завершается, все его страницы памяти мгновенно переходят в «доступ». ; пуф & Quot ;. Таким образом, хотя язык не гарантирует его, он, тем не менее, происходит надежно. Обратите внимание, что я не говорю, что на это можно положиться ...
4

1) Освободите память, когда вы запросите, если с кучи Утечки памяти никогда не бывают хорошими..

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

Любая ОС, которая не очищала эту память, является дерьмом. Это будет означать, что любой сбой приложения в этой ОС навсегда оставит эти утечки ресурсов. Стандартный malloc / new создает память приложения, нет никаких оснований полагать, что она сохраняется после окончания этого приложения.
@ edA-qa mort-ora-y Хорошо. Не имеет большого значения, как вы выбираете слова для такой системы? Ну что ж. Жизнь идет.
Если он не очищает память, я бы не назвал это ОС. В этот момент это просто уровень абстракции устройства.
2

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

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

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

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

4

«всегда бесплатно то, что вы выделили»; Принцип хорош для двух вещей:

If your program leaks memory but never exits (daemons, servers, ...) continuously leaking memory will waste RAM badly.

You should not defer freeing all memory until your program terminates (like Firefox does sometimes - noticed how much time it takes for it to exit?) - the point is to minimalize the time for which you have allocated memory; even if your program continues to run, you should immediately free up allocated RAM after you are finished with it.

@SanJacinto: я знаю. Но я рассматриваю только основные ядра, которые используют 99% устройств с реальной вычислительной мощностью. И большинство из них - DOS (я не знаю), Linux (вызывающе), OSX Mach / XNU (вызывающе), Windows NT (делает) или другие UNIX (скорее всего).
@ SanJacin, ты думаешь, я предложил не убирать за собой? Я не делал. Я только что сказал, что ожидаю от достойной ОС очистки в случае выхода из процесса -in case the programmer accidentally forgot to do so.
Что ж, ваше предположение неверно - я работал со множеством этих встроенных ОС - но я думаю, что они здесь немного выходят за рамки, поскольку я не думаю, что OP в первую очередь рассматривал специальные встроенные системы, подходящие системы или что-то подобное. ; экзотическое & APOS; - видя из его профиля, я думаю, что он хотел знать только о добром старом; ПК. Хотя ты технически прав, я чувствую, что этот разговор стал скорее бессмысленным аргументом, и я не хочу начинать троллинг.
@SanJacinto: Хотя любое крупное ядро в настоящее время будет очищать вашу память после того, как вы спасете систему от ожидаемого бедствия из-за нехватки памяти. NT будет, Mach / XNU будет, Linux будет, BSD будет и т. Д.
Хорошо, сколько операционных систем реального времени и облегченных систем вы рассматривали? Я понимаю, что это обычное поведение, и это делает его еще хуже. Если вы увековечите мысль, что «все хорошо» Если вы сделаете это, тогда у кого-нибудь будет неприятный сюрприз.
1

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

4

операционная система, используемая старыми компьютерами Amiga (& # x201C; AmigaOS & # x201D;), не имела полного управления памятью, как предполагается сейчас (за исключением, возможно, некоторых более поздних версий, выпущенных, когда Amiga больше не была популярна).

Процессор не имел MMU (блок управления памятью), и, как следствие, каждый процесс имел доступ ко всей физической памяти. Из-за этого, когда два процесса хотели поделиться некоторой информацией, они могли просто обмениваться указателями. Эта практика была даже поощрена ОС, которая использовала эту технику в своей схеме передачи сообщений.

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

0

потому что представьте, что вы выделяете много памяти во многих местах и НЕ освобождаете ее. После выделения памяти она занимает часть памяти, которая больше не может быть выделена. Это приведет к тому, что объем доступной памяти будет уменьшаться и уменьшаться с каждым разом, поскольку вы не можете ее освободить. В какой-то момент память будет исчерпана. Даже если память освобождается при завершении программы, представьте, что ваша программа работает несколько недель подряд, постоянно выделяя память, но никогда не освобождая ее. Память - это ограниченный ресурс, и вы должны нести ответственность при использовании динамического распределения.

3

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

Именно так. Потому что представьте, если система находится под высокой нагрузкой? Программа, которая не освобождает свою память, приведет к дорогостоящим переключениям контекста и потере памяти. Если вы не пишете специальное, критически важное программное обеспечение, которое будет работать только в одиночку и не сможет выдержать снижение производительности при использованииmalloc or free (но используя техники низкого уровня), тогда вы можете подумать о том, чтобы не освобождать.

Похожие вопросы