Нет, завершение программы, как с exit
или abort
, не освобождает память так же, как free
. Использование free
вызывает некоторые действия, которые в конечном итоге не действуют, когда операционная система отбрасывает данные, поддерживаемые malloc
и free
.
exit
имеет некоторые сложности, поскольку не приводит к немедленному завершению программы. А пока давайте просто рассмотрим эффект немедленного завершения программы и рассмотрим осложнения позже.
В многопользовательской операционной системе общего назначения, когда процесс завершается, операционная система освобождает память, которую она использовала для других целей. 1 По большей части это просто означает, что операционная система выполняет некоторые бухгалтерские операции.
Напротив, когда вы вызываете free
, программное обеспечение внутри программы запускается, и оно должно искать объем памяти, которую вы освобождаете, а затем вставлять информацию об этой памяти в пул памяти, который она поддерживает. Таких распределений может быть тысячи или десятки тысяч (или больше). Программа, которая освобождает все свои данные, может выполнять тысячи вызовов на free
. Тем не менее, в конце концов, когда программа завершает работу, все изменения, произведенные free
, исчезают, так как операционная система отбрасывает все данные об этом пуле памяти - все данные находятся на страницах памяти, которые делает операционная система. не сохранить.
Таким образом, ответ, который вы ссылаетесь на , является правильным, призыв free
- пустая трата времени И, как он указывает, необходимость проходить через все структуры данных в программе для извлечения указателей в них, чтобы освободить память, на которую они указывают, заставляет все эти структуры данных считываться в память, если они были выгружены на диск. Для больших программ это может занять значительное количество времени и других ресурсов.
С другой стороны, не ясно, можно ли избежать многих звонков на free
. Это связано с тем, что освобождение памяти - это не единственное, что должна завершать завершающая программа. Программа может захотеть записать окончательные данные в файлы или отправить окончательные сообщения в сетевые подключения. Кроме того, программа, возможно, не установила весь этот контекст непосредственно. Большинство крупных программ используют слои программного обеспечения, и каждый программный пакет может иметь свой собственный контекст, и зачастую нет никакого способа сообщить другому программному обеспечению: «Я хочу выйти сейчас. Завершите ценный контекст, но пропустите все освобождение памяти ». Таким образом, все желаемые задачи очистки могут быть переплетены с задачами свободной памяти, и, возможно, нет никакого хорошего способа распутать их.
Программное обеспечение, как правило, должно быть написано так, чтобы ничего не происходило, если программа внезапно прерывается (поскольку это может произойти из-за потери мощности, а не только из-за преднамеренных действий пользователя). Но даже при том, что программа может быть в состоянии терпеть прерывание, все же может быть значение в изящном выходе.
Возвращаясь к exit
, вызов подпрограммы C exit
не приводит к немедленному выходу из программы. Вызываются обработчики выхода (зарегистрированные с atexit
), буферы потоков сбрасываются, а потоки закрываются. Любые библиотеки программного обеспечения, которые вы вызывали, могли настроить свои собственные обработчики выхода, чтобы они могли завершать работу при выходе из программы. Итак, если вы хотите быть уверены, что библиотеки, которые вы использовали в своей программе, не вызывают free
при завершении программы, вы должны вызвать abort
, а не exit
. Но обычно предпочитается завершать программу изящно, а не прерывать ее. Вызов abort
не будет вызывать обработчики выхода, сбрасывать потоки, закрывать потоки или выполнять другой свернутый код, который exit
делает - данные могут быть потеряны, когда программа вызывает abort
.
Сноска
1 Освобождение памяти не означает, что она сразу доступна для других целей. Конкретный результат этого зависит от каждой страницы памяти. Например:
- Если тПамять разделяется с другими процессами, она все еще необходима для них, поэтому освобождение ее от использования этим процессом только уменьшает количество процессов, использующих память. Он не сразу доступен для любого другого использования.
- Если память не используется какими-либо другими процессами, но содержит данные, сопоставленные с файлом на диске, операционная система может пометить ее как доступную при необходимости, но на время оставить ее в покое. Это потому, что вы могли бы снова запустить ту же программу, и было бы неплохо, если бы данные оставались в памяти, так почему бы просто не оставить ее на месте на всякий случай? Данные могут даже использоваться другой программой, которая использует тот же файл. (Например, многие программы могут использовать одну общую библиотеку.)
- Если память не используется какими-либо другими процессами и просто использовалась программой как рабочая область, а не отображалась из файла, то система может пометить ее как доступную сразу и не содержащую ничего полезного.