Разрешает ли ISO C зависание выделенной памяти после завершения программы?

Интересный момент возник у некоторых моих коллег, некоторые из которых утверждают, что вы всегда должны 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), что выделенная память может продолжать потреблять ресурсы даже после того, как процесс, который ее выделил, ушел?

Или я что-то пропустил в стандарте, что делает это спорным?


person paxdiablo    schedule 08.02.2013    source источник
comment
Все, что вы упустили, это то, что концепция процессов или все, что происходит после завершения процесса, полностью выходит за рамки стандарта C, и поэтому, конечно, стандарт ничего не говорит об этом.   -  person R.. GitHub STOP HELPING ICE    schedule 08.02.2013


Ответы (1)


Очистка выделенной памяти после завершения программы подпадает под компетенцию ОС, а не стандарта C.

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

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

person Karthik T    schedule 08.02.2013
comment
Встроенные ОС подпадают под автономную часть стандарта, где разрешено практически все :-) - person paxdiablo; 08.02.2013
comment
Действительно, что касается стандарта C, мир заканчивается, когда main возвращается или вызывается exit. Нет понятия процессов или постоянства чего-либо. Любая реальная система, которая имеет такие концепции, будет определять, какие ресурсы, если таковые имеются, сохраняются после завершения процесса, и память, полученная malloc, никогда не сохраняется. - person R.. GitHub STOP HELPING ICE; 08.02.2013
comment
Можно с уверенностью сказать, что в любой системе, которая поддерживает отдельные области виртуальной памяти для каждого процесса, карта процесса будет уничтожена, когда проект выйдет или будет собран, и все страницы, назначенные исключительно ему (независимо от того, получены ли они с помощью malloc или каким-либо другим способом), будут возвращены. к системе. - person Variable Length Coder; 08.02.2013
comment
В Atari TOS (я знаю, что она старая) некоторые компиляторы используют системную функцию Malloc. Там может случиться так, что выделенная память останется выделенной после запуска программы. Это раздражало, потому что также было ограниченное количество распределений, которые можно было сделать. - person Patrick Schlüter; 09.02.2013