Типичная схема памяти запущенного процесса
1. Текстовый сегмент:
Текстовый сегмент, также известный как сегмент кода или просто как текст, является одним из разделов программы в объектном файле или в памяти, которая содержит исполняемые инструкции.
В качестве области памяти текстовый сегмент может быть размещен ниже кучи или стека, чтобы предотвратить его перезапись в кучах и переполнениях стека.
Обычно текстовый сегмент является разделяемым, поэтому для часто выполняемых программ, таких как текстовые редакторы, компилятор C, оболочки и т. Д., Должна быть только одна копия. Кроме того, текстовый сегмент часто доступен только для чтения, чтобы программа не могла случайно изменить свои инструкции.
2. Инициализированный сегмент данных:
Инициализированный сегмент данных, обычно называемый просто Сегмент данных. Сегмент данных — это часть виртуального адресного пространства программы, которая содержит глобальные переменные и статические переменные, которые инициализируются программистом.
Обратите внимание, что сегмент данных не только для чтения, так как значения переменных могут быть изменены во время выполнения.
Этот сегмент может быть дополнительно классифицирован на инициализированную область только для чтения и инициализированную область чтения-записи.
Например, глобальная строка, определенная char s [] = «hello world» в C и оператором C, например int debug = 1 вне основного (т. Е. Глобального), будет храниться в инициализированной области чтения-записи. А глобальный оператор C, такой как const char * string = «hello world», заставляет строковый литерал «hello world» храниться в инициализированной области только для чтения, а переменную-строку указателя символов — в инициализированной области чтения-записи.
Пример: static int i = 10 будет сохранено в сегменте данных, а глобальное int i = 10 также будет сохранено в сегменте данных
3. Сегмент неинициализированных данных:
Сегмент неинициализированных данных, часто называемый сегментом «bss», названный в честь древнего оператора ассемблера, который обозначал «блок, начинающийся с символа». Данные в этом сегменте инициализируются ядром в арифметику 0 до начала выполнения программы
неинициализированные данные начинаются в конце сегмента данных и содержат все глобальные переменные и статические переменные, которые инициализированы нулем или не имеют явной инициализации в исходном коде.
Например, переменная, объявленная как static int i; будет содержаться в сегменте BSS.
Например, глобальная переменная, объявленная int j; будет содержаться в сегменте BSS.
4. Стек:
Область стека традиционно примыкала к области кучи и росла в противоположном направлении; когда указатель стека встретился с указателем кучи, свободная память была исчерпана. (С современными большими адресными пространствами и методами виртуальной памяти они могут быть размещены почти где угодно, но они все еще обычно растут в противоположных направлениях.)
Область стека содержит программный стек, структуру LIFO, обычно расположенную в верхних частях памяти. На стандартной компьютерной архитектуре ПК x86 она растет до нуля адресов; на некоторых других архитектурах он растет в противоположном направлении. Регистр «указатель стека» отслеживает вершину стека; он корректируется каждый раз, когда значение «помещается» в стек. Набор значений, выдвигаемых для одного вызова функции, называется «стековым фреймом»; Фрейм стека состоит как минимум из обратного адреса.
Стек, где хранятся автоматические переменные, а также информация, которая сохраняется при каждом вызове функции. Каждый раз, когда вызывается функция, адрес стека, к которому следует вернуться, и определенная информация о среде вызывающего, например, некоторые из регистров машины, сохраняются в стеке. Затем вновь вызванная функция выделяет место в стеке для его автоматических и временных переменных. Вот как могут работать рекурсивные функции в Си. Каждый раз, когда рекурсивная функция вызывает себя, используется новый кадр стека, поэтому один набор переменных не мешает переменным из другого экземпляра функции.
5. Куча:
Куча — это сегмент, где обычно происходит динамическое распределение памяти.
Область кучи начинается в конце сегмента BSS и увеличивается оттуда к более крупным адресам. Область кучи управляется malloc, realloc и free, которые могут использовать системные вызовы brk и sbrk для настройки своего размера (обратите внимание, что использование brk / sbrk и одной «области кучи» не требуется для выполнения контракта malloc / realloc / free; они также могут быть реализованы с использованием mmap для резервирования потенциально несмежных областей виртуальной памяти в виртуальном адресном пространстве процесса) , Область Heap является общей для всех общих библиотек и динамически загружаемых модулей в процессе.