Куда идут неинициализированные глобальные переменные после инициализации? - PullRequest
8 голосов
/ 11 августа 2009

У меня возникла небольшая проблема при обучении. Я знаю, что неинициализированные глобальные переменные в C назначаются разделу .bss в исполняемом файле ELF. Но что с ними происходит, когда я начинаю их использовать? То есть они получают место в куче или где-то еще?

Я попытался выяснить, напечатав адрес глобальной (все еще неинициализированной) глобальной переменной с помощью

printf("%x",&glbl);

, которые всегда возвращают одно и то же значение 0x80495bc ... Почему?

Ответы [ 4 ]

8 голосов
/ 11 августа 2009

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

2 голосов
/ 11 августа 2009

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

1 голос
/ 11 августа 2009

Эта секция BSS получает блок памяти в адресном пространстве процесса, так же, как секции кода и стека (и любые другие ELF могут иметь) Оказавшись там, они никуда не денутся. Загрузчик упорядочивает вещи, затем вызывает точку входа в процесс.

1 голос
/ 11 августа 2009

BSS - это заполнитель, определенный в формате вашего исполняемого файла (или ELF). Таким образом, он не занимает дисковое пространство, а только указывает, какая область памяти должна быть выделена компоновщиком или загрузчиком.

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

В случае, если вы строите для операционной системы (например, Linux), загрузчик из операционной системы выполнит этап перемещения, на котором он сопоставляет все местоположения, помеченные как относительные в исключительном формате, с физическими или логическими местоположениями в памяти. 1005 *

Поскольку вы упоминаете, что всегда видите одно и то же значение, это означает, что процесс повторяется для вашей системы. Ожидайте увидеть изменения при изменении файлов компоновщика (т. Е. Адресных областей), порядка компоновки (т. Е. Модули получат назначенное пространство в другом порядке) или операционной системы.

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

...