Действительно ли мы должны free(), когда мы используем malloc()? Чем он тогда отличается от автоматической переменной?
ОС просто восстановит его (после выхода из программы), верно? Так что толку, кроме хорошего стиля программирования? Или я что-то недопонимаю? Чем он отличается от "автоматического" распределения, поскольку оба могут быть изменены во время выполнения, и оба заканчиваются после выполнения программы?
8 ответов
Когда ваше приложение работает с огромными объемами данных, вы должны освободить его, чтобы сэкономить пространство кучи. Если вы этого не сделаете, может произойти несколько плохих вещей:
- ОС перестанет выделять память для вас (сбой)
- ОС начнет выгружать ваши данные на диск (перебивать)
- другие приложения будут иметь меньше места для размещения своих данных
Тот факт, что ОС собирает все пространство, которое вы выделяете при выходе из приложения, не означает, что вы должны полагаться на это при написании надежного приложения. Это все равно что пытаться полагаться на компилятор для оптимизации плохого программирования. Управление памятью имеет решающее значение для хорошей производительности, масштабируемости и надежности.
Как уже упоминали другие, malloc
выделяет пространство в куче, а в стеке создаются автоматические переменные. Существуют варианты использования обоих, но они действительно очень разные. Пространство кучи должно выделяться и управляться ОС и может хранить данные динамически и разных размеров.
Если вы вызываете макрос тысячу раз без использования free(), то компилятор или система безопасных сообщений скажет, что система назначит вам тысячу разных адресов, но если вы используете free() после каждого malloc, тогда каждый раз будет предоставляться только один адрес памяти. Таким образом, вероятность утечки памяти, ошибки шины, нехватки памяти и сбоя будет минимальной. Его безопасно использовать бесплатно ().
Это хороший стиль программирования, и это больше, чем это. Неправильное управление памятью в нетривиальных программах в конечном итоге повлияет на удобство использования вашей программы. Конечно, ОС может вернуть любые ресурсы, которые вы выделили / использовали после завершения вашей программы, но это не уменьшает нагрузку или потенциальные проблемы во время выполнения программы.
Рассмотрим веб-браузер, который вы использовали для публикации этого вопроса: если браузер написан на языке, который требует управления памятью, а код не выполнял это должным образом, как вы думаете, сколько времени пройдет, прежде чем вы заметите что это пожирает всю твою память? Как вы думаете, как долго браузер будет работать? Теперь учтите, что пользователи часто оставляют браузеры открытыми на долгое время: без надлежащего управления памятью они станут непригодными для использования после нескольких загрузок страниц.
В C/C++ "автоматические" переменные размещаются в стеке. Они уничтожаются прямо на выходе из функции. Это произойдет автоматически. Вам не нужно ничего писать для этого.
Распределение кучи (результат вызова malloc
) либо освобождены явно (с вызовом free
) или они очищаются, когда процесс заканчивается.
Если вы пишете небольшую программу, которая будет использоваться, может быть, один или два раза, тогда все в порядке, не освобождая ваши кучи. Это не приятно, но приемлемо.
Если вы пишете средний или большой проект или планируете включить свой код в другой проект, вам определенно следует освободить каждое выделение кучи. Отказ от этого создаст ОГРОМНЫЕ проблемы. Память кучи не бесконечна. Программа может использовать все это. Даже если вы выделите небольшой объем памяти, это все равно будет создавать непреднамеренную нагрузку на ОС, вызывать перестановку и т. Д.
Суть в том, что освобождение ассигнований - это больше, чем просто стиль или хорошая привычка.
Автоматическая переменная уничтожается (и ее память используется повторно), как только вы выходите из области действия, в которой она определена. Для большинства переменных это намного раньше, чем выход из программы.
если ты malloc
и не free
, то память не может быть повторно использована до выхода из программы. Даже тогда, на некоторых системах с очень минимальной ОС.
Так что да, есть большая разница между автоматической переменной и утечкой памяти. Вызовите функцию, которая выделяет выделение достаточно раз, и вам не хватит памяти. Вызывайте функцию с автоматической переменной столько раз, сколько захотите, память можно использовать повторно.
Если ваша программа не завершается немедленно и вы не освобождаете свою память, вы в конечном итоге будете ее тратить. Либо у вас в конце концов закончится память, либо вы начнете переставлять на диск (что медленно, а также не безгранично).
Автоматическая переменная находится в стеке, и ее размер должен быть известен во время компиляции. если вам нужно хранить данные, размер которых вам не подходит, например, поддерживать двоичное дерево, в котором пользователь добавляет и удаляет объекты. Кроме того, размер стека может быть ограничен (зависит от вашей цели), например, для ядра Linux, стек обычно составляет 4k-8k. вы также удаляете кеш инструкций, который влияет на производительность,
Да, вам обязательно нужно использовать free() после malloc() (а также закрывать файлы и другие ресурсы, когда вы закончите). Несмотря на то, что операционная система восстановит ее после выполнения, длительный процесс приведет к утечке памяти. Если ваша программа так же проста, как основной метод, который запускает один метод, то он существует, вероятно, это не имеет большого значения, хотя и невероятно небрежно. Вы должны привыкнуть правильно управлять памятью в C, потому что однажды вы захотите написать нетривиальную программу, которая будет выполняться более секунды, и если вы не научитесь делать это заранее, у вас будет огромная головная боль, связанная с утечками памяти.