C Статическое и автоматическое размещение

Когда запускается программа C, как она запрашивает у операционной системы достаточно места в памяти для статических переменных? И как он во время работы запрашивает автоматические переменные в памяти операционной системы?

Я также хотел бы знать, как он освобождает эти области памяти после выполнения.

Пожалуйста, постарайтесь быть максимально точными. Если операционные системы различаются в своих объяснениях, пожалуйста, отдайте предпочтение UNIX-подобным.


person Thiago Bezerra    schedule 02.03.2015    source источник


Ответы (3)


Глобальные переменные и переменные со статическим временем жизни обычно хранятся в сегменте данных, который настраивается загрузчиком исполняемых файлов операционной системы.

Этот загрузчик, вероятно, делает то, что сказал @John Zwinck о Unix. Например, в Windows есть VirtualAlloc, который также можно использовать для выделения памяти в адресном пространстве другой программы.

Локальные переменные обычно хранятся в так называемом стеке. Выделения в стеке выполняются довольно быстро, поскольку обычно они состоят только из модификации регистра указателя стека (sp, esp, rsp в семействе процессоров x86). Поэтому, когда у вас есть int (размер: 4 байта), этот регистр будет просто уменьшаться на 4 по мере роста стека вниз. В конце области видимости восстанавливается старое состояние регистра стека.

Также это делает опасным переполнение стека, когда вы можете перезаписать другие переменные в стеке, которые не должны быть изменены, например, адреса возврата вызовов функций.

Динамические переменные - это переменные, выделяемые с помощью malloc (C) или new (C ++), или любой из функций выделения, специфичных для операционной системы. Они помещаются в так называемую кучу. Они живут до тех пор, пока не будут очищены с помощью free / delete / os-specific-deallocator или пока программа не завершится (в этом случае разумная операционная система позаботится об очистке).

Кроме того, динамическое размещение является самым медленным из трех, поскольку требует обращения к операционной системе.

person Felix Bytow    schedule 02.03.2015

Выделение памяти в Unix-подобных системах осуществляется через вызовы операционной системы с использованием sbrk() и API mmap().

sbrk() используется для увеличения «сегмента данных», который представляет собой непрерывный диапазон (виртуальных) адресов. mmap() используется во многих современных системах как своего рода дополнение к этому, потому что он может выделять блоки, которые впоследствии могут быть освобождены независимо (что означает, что никаких «дыр» не останется, как это может случиться с sbrk()).

В C у вас есть malloc() как пользовательский API для распределения памяти. Вы можете узнать больше о том, как это соотносится с функциями низкого уровня, о которых я упоминал ранее, здесь: Как реализованы malloc и free?

person John Zwinck    schedule 02.03.2015

Статические переменные находятся в сегменте BSS за кодом. Автоматические переменные располагаются в стеке в конце виртуальной памяти процесса. Оба определены во время компиляции. Структура памяти затем создается при запуске программы. brk (), sbrk () и mmap () могут управлять виртуальной памятью (в частности, кучей) во время выполнения (например, с помощью malloc () / free ()), но эти функции не связаны со статическими и автоматическими переменными!

person Bernhard    schedule 02.03.2015