Распределение памяти и инициализация происходят отдельно во время компиляции и выполнения? - PullRequest
0 голосов
/ 31 мая 2019

Когда мы объявляем переменную, скажем, int, я хотел бы знать, какие шаги выполняются во время выделения памяти и инициализации. а также для указателя

int x = 5;

теперь во время компиляции 4 байта выделяется целому числу x. но когда память заполняется значением 5? Происходит ли инициализация во время компиляции или выполнения во время выполнения. аналогично рассмотрим

int x = 5;
int* p = &x;

в этих 2 строках что такое процесс выделения и инициализации.

Ответы [ 2 ]

1 голос
/ 31 мая 2019

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

Глобальные переменные

  • Во время компиляции,значение всех глобальных переменных известно.Эти значения записываются компилятором в определенные разделы объектного файла.

  • Во время компоновки все объектные файлы собираются и для каждой переменной определяются места в памяти.Это позволяет узнать адрес каждой переменной в случае, если один из этих адресов назначен другой переменной.
    В результате создается исполняемый файл, содержащий описание содержимого каждого раздела (текст, данные, родата)., так далее).В разделе data или rodata записываются значения всех инициализированных глобальных переменных.

  • во время выполнения, загрузчик считывает описание различных разделов и запрашивает память операционной системы.Затем он скопирует содержимое всех разделов в соответствующие ячейки памяти.
    Таким образом, переменная инициализируется значением, определенным во время компиляции или компоновки.
    Единственное исключение - переменные, которые инициализируются с нуля (или не инициализирован).Они расположены в специальном разделе (часто называемом bss).Чтобы уменьшить размер исполняемых файлов, эти нулевые значения не записываются в исполняемый файл.Вместо этого, перед выполнением main(), во время выполнения процедура memset обнулит все содержимое секции bss.

Автоматические переменные

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

Таким образом, компилятор сначала определяет, будут ли эти переменные находиться в регистре или памяти, и когдаПри входе в функцию первыми инструкциями будет резервирование стекового пространства для локальных переменных и инициализация их значений.Это делается с помощью обычных машинных инструкций.

В случае, если значением является адрес другой переменной (скажем, y = & x),
*, если x является локальной (автоматической) переменной, адрес будетвычисляется путем записи в y суммы содержимого регистра указателя стека и заданного смещения, определенного компилятором
*, если x является глобальной или статической переменной, во время соединения, как только адреса глобальных переменныхизвестно, что компоновщик изменяет инструкции, сгенерированные компилятором, чтобы записать правильный адрес в регистр или место в стеке, используемое для представления y.

0 голосов
/ 02 июня 2019

Существуют ситуации, когда нет способа определить во время выполнения: if user_input == "yes": my_var = 5 еще: my_var = 7

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

...