Интересный момент возник у некоторых моих коллег, некоторые из которых утверждают, что вы всегда должны free
помнить, что вы malloc
несмотря ни на что. Хотя я всегда считал, что это хорошая практика в целом, некоторые другие утверждали, что это не обязательно в таких программах, как:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *mem = malloc (1000);
if (mem != NULL) {
// do something with mem
}
// memory not freed
return 0;
}
Они утверждали, что память будет очищаться при завершении процесса.
Теперь, будучи местным стандартным убер-компьютерщиком, они обратились ко мне за разъяснениями, и, к моему удивлению, кажется, что всегда свободная толпа может на самом деле быть правильной.
Обращаясь к C11, 5.1.2.2.3 Program termination
, просто говорится, что достижение конца main
идентично вызову exit
.
7.22.4.4 The exit function
перечисляет те вещи, которые очищаются, а именно:
- вызвать все обработчики
atexit
. - все открытые потоки с незаписанной буферизацией сбрасываются.
- все открытые потоки закрыты.
- все файлы, созданные
tmpfile
, закрыты. - управление возвращается в окружающую среду.
Там не упоминается об очистке выделенной памяти.
Теперь, глядя на 6.2.4 Storage duration of objects
, он упоминает четыре длительности хранения, из которых «выделено» представляет интерес здесь. Далее в нем говорится, что:
Выделенное хранилище описано в 7.22.3.
7.22.3 Memory management functions
определяют поведение всех наших любимцев, таких как malloc
и free
. Нигде не упоминается, что происходит с памятью, которая не была освобождена до завершения процесса. В нем просто говорится:
Время жизни выделенного объекта простирается от выделения до освобождения.
Имейте в виду, что это не вопрос того, что делают реализации — я хорошо знаю, что почти каждая реализация, которую я когда-либо видел, хранит свою область памяти в пространстве процесса и что она сбрасывается при выходе из процесса. Это то, что разрешено стандартом ISO C.
Я не могу найти ничего в стандарте, который предписывает это поведение «освобождается при завершении», поэтому возможна реализация, в которой выделенная память пережила завершение процесса (подумайте, например, о malloc
, который использует постоянную общую память).
Так вот вопрос. Возможно ли (согласно ISO C), что выделенная память может продолжать потреблять ресурсы даже после того, как процесс, который ее выделил, ушел?
Или я что-то пропустил в стандарте, что делает это спорным?