Автоматическое выделение памяти происходит во время компиляции или во время выполнения на C?

#c #memory #scope #static #auto

#c #память #область #статический #авто

Вопрос:

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

Если я говорю об автоматическом распределении памяти, оно выделяется, когда элемент управления входит в новую область. Теперь я сомневаюсь, что в этом случае также появляется компилятор и передает некоторые виртуальные адреса в скомпилированный двоичный файл, который позже становится адресами фактической выделенной памяти во время выполнения, или эта память выделяется только во время выполнения без какой-либо роли компилятора, точно так же, как выделяется динамическая память?

Что, если у меня есть какая-то локальная переменная, например:

 int a = 10;
  

Будет ли у него выделение времени компиляции или времени выполнения?

Комментарии:

1. Компилятор может оптимизировать эту переменную (без выделения памяти), использовать регистр только для этой переменной (без выделения памяти) или генерировать инструкции для выделения для нее места в стеке.

Ответ №1:

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

В случае, если они попадают в стек, компилятор создает локальное смещение области видимости для функции, в которой выделена переменная. То есть переменная может называться как SP 8 или что-то подобное, где SP — указатель стека. Которое, в свою очередь, может содержать любое значение при вводе функции — компилятор или машинный код не знают или не заботятся об этом, поэтому существуют переполнения стека.

Вы можете найти это полезным: что выделяется в стеке и куче ?.

Комментарии:

1. Если я все правильно понял, это означает, что компилятор создаст смещения области видимости, но фактическое выделение для них будет выполняться только во время выполнения?

2. @LocalHost Да, они выделяются либо с помощью специальных push-инструкций, либо как часть стекового фрейма, в зависимости от ISA и ABI.

Ответ №2:

Локальные переменные помещаются в стек, когда они хранятся в памяти.

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

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

Однако в оптимизированных сборках локальные переменные часто также хранятся в регистрах процессора (когда доступно достаточно регистров) и не обязательно хранятся в памяти вообще. Цель этого — избежать обращений к памяти, чтобы ускорить программу. Распределение регистров (компилятор выбирает, какие переменные хранить в регистрах и какой регистр использовать для какой переменной) зависит от большого количества черной магии, которую выполняет компилятор, анализируя время жизни переменной и сколько она используется.