Освобождение в атаке ()
Есть ли смысл освобождать память в функции atexit()?
У меня есть глобальная переменная, которая получает malloc'ed после запуска. Я мог бы написать функцию atexit(), чтобы освободить ее, но разве система все равно не освободит всю эту память при выходе из программы?
Есть ли польза в том, чтобы быть аккуратным и активно убирать его сам?
8 ответов
Не в С - это все равно что переставлять шезлонги, пока корабль тонет вокруг вас.
В C++ ответ другой, потому что объекты могут удалять временные файлы и т. Д. В своих деструкторах, поэтому вам нужно убедиться, что они были вызваны.
Одно из преимуществ освобождения состоит в том, что если вы когда-нибудь проведете какое-либо тестирование утечки памяти, которое пытается сопоставить выделение с освобождением в течение срока службы процесса, вы не получите ложных срабатываний от такого намеренного утечки.
Видеть как malloc()
/free()
обычно включают в себя обширные структуры данных, которые существуют в пространстве пользователя, free()
Память, когда ваша программа заканчивается, может привести к снижению производительности. Если части структуры данных выгружаются на диск, их нужно загружать с диска только для удаления!
Принимая во внимание, что если вы прекратите без free()
Однако данные, выгруженные на диск, могут умереть спокойно.
Конечно free()
в другое время обычно выгодно, поскольку в дальнейшем malloc()
s может повторно использовать пространство, которое вы освободили и free()
может даже удалить карту памяти, которая затем может быть использована другими процессами.
Во всех современных операционных системах можно смело предполагать, что вся память будет освобождена при выходе из программы.
На самом деле быть аккуратным может быть интересно, когда ваша программа развивается. Это заставляет вас писать функцию очистки при создании функций "инициализации". Преимущество приходит, когда ваша программа становится более сложной, и вы хотите перезапустить часть программы. Если вы уже написали работающие функции очистки, менее вероятно, что вы вдруг забыли какую-то очистку при "перезапуске" части вашей программы.
Написание функций очистки "лениво", т.е. только тогда, когда вам это нужно, более подвержено ошибкам. Написание функций очистки заставляет задуматься об очистке и возможной зависимости очистки. Это позволяет упростить повторное использование части кода в другом проекте.
Так что да, освобождение в atexit бесполезно, как и закрытие файлового дескриптора. Однако написание и поддержание функции очистки по мере роста вашего кода может быть ограничением, которое заставит вас задуматься о том, что вы делаете
Вы должны освободить (), если ваш код, вызывающий atexit (), является частью динамически загружаемой разделяемой библиотеки (например, с помощью dlopen ()). В этом случае обработчик atexit будет вызываться во время dlclose (), поэтому куча будет продолжать существовать до конца процесса.
В Windows некоторые вызовы возвращают память, принадлежащую ОС или COM, и вам необходимо явно освободить эту память, иначе она не будет освобождена даже после завершения вашего процесса. Но это редкий сценарий.
Не освобождение памяти до завершения процесса не является утечкой памяти. это утечка памяти, когда вы теряете ручку к нему. но память не является единственным типом ресурса, и другие ресурсы сохраняются во всех процессах (например, дескрипторы окон и дескрипторы файлов), поэтому вам необходимо их "освободить".