Адрес ( & ) дает компилятору сгенерированный адрес или загрузчику сгенерированный адрес?


int a;
printf("address is %u", &a);

Какой это адрес?.? Я имею в виду, является ли это адрес, сгенерированный компилятором, то есть виртуальный адрес, или загрузчик задал физический адрес в оперативной памяти..?

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

Пожалуйста, укажите любые ссылки, которые дают ссылку на ваш ответ.

4 4

4 ответа:

Правильный ответ: "это зависит от обстоятельств."

(printf должен использовать директиву "%p" и привести адрес к " void *", ради четкого определения:

printf("%p\n", (void *)&a);

Хотя использование %u, несомненно, работает для вашего конкретного компилятора с любыми флагами, которые вы используете.)

Как отметил @Alex, адрес является виртуальным, если перевод продолжается (как и в большинстве современных ОС, или даже при запуске в "эмулированном физическом" под виртуальной машиной). Сам адрес, как правило, определяется во время соединения или загрузки, если "a" имеет статическую длительность хранения, но во время выполнения (в стеке, как сказал @Als), если нет. Переменные, объявленные "static" или "extern", имеют статическую длительность; переменные, объявленные вне тел функций, имеют статическую длительность; а переменные, объявленные внутри тел функций, но без использования "extern" или "static", имеют автоматическую длительность хранения (и поэтому обычно находятся в "стеке" -хотя может быть несколько стеков, как при использовании потоков POSIX).

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

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

В любой современной ОС Все адреса, которые вы когда-либо видели на уровне C, являются виртуальными адресами. Пример, который вы приводите, - это переменная в стеке, и причина, по которой это будет отличаться при каждом выполнении, заключается в том, что (виртуальный) адрес стека рандомизирован по соображениям безопасности.

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

(Все это может быть неверно для встроенных устройств, но это обычно нет ничего, с чем вы столкнетесь при изучении C)

Я имею в виду, является ли это адрес, сгенерированный компилятором, то есть виртуальный адрес или загрузчик задал физический адрес в оперативной памяти.

Ложная дихотомия. Адрес, сгенерированный компилятором, перемещается компоновщиком, и именно этот адрес возвращается &. Это виртуальный адрес, если вы не работаете на чем-то странном, как NetWare 3, который не использует виртуальную машину.