Адрес ( & ) дает компилятору сгенерированный адрес или загрузчику сгенерированный адрес?
int a;
printf("address is %u", &a);
Какой это адрес?.? Я имею в виду, является ли это адрес, сгенерированный компилятором, то есть виртуальный адрес, или загрузчик задал физический адрес в оперативной памяти..?
Поскольку он каждый раз печатает разные адреса, я предполагаю, что это должен быть адрес в оперативной памяти. Просто хочу убедиться.
Пожалуйста, укажите любые ссылки, которые дают ссылку на ваш ответ.
4 ответа:
Правильный ответ: "это зависит от обстоятельств."
(printf должен использовать директиву "%p" и привести адрес к " void *", ради четкого определения:
printf("%p\n", (void *)&a);
Хотя использование %u, несомненно, работает для вашего конкретного компилятора с любыми флагами, которые вы используете.)
Как отметил @Alex, адрес является виртуальным, если перевод продолжается (как и в большинстве современных ОС, или даже при запуске в "эмулированном физическом" под виртуальной машиной). Сам адрес, как правило, определяется во время соединения или загрузки, если "a" имеет статическую длительность хранения, но во время выполнения (в стеке, как сказал @Als), если нет. Переменные, объявленные "static" или "extern", имеют статическую длительность; переменные, объявленные вне тел функций, имеют статическую длительность; а переменные, объявленные внутри тел функций, но без использования "extern" или "static", имеют автоматическую длительность хранения (и поэтому обычно находятся в "стеке" -хотя может быть несколько стеков, как при использовании потоков POSIX).
Адрес, возвращаемый для локальной переменной в пользовательском пространстве, всегда является виртуальным адресом, а не физическим адресом.
Переменная
a
в вашем случае выделяется на локальном хранилище (стеке), и каждый раз, когда вы выполняете вашу программу, пространство стека, выделенное для вашей функции, переменная находится с определенным смещением в пределах этого кадра стека, так как адрес стека, выделяемого вашей программе, может быть различным каждый раз, когда адрес, возвращаемый для переменной, будет изменен. и тоже разные.
В любой современной ОС Все адреса, которые вы когда-либо видели на уровне C, являются виртуальными адресами. Пример, который вы приводите, - это переменная в стеке, и причина, по которой это будет отличаться при каждом выполнении, заключается в том, что (виртуальный) адрес стека рандомизирован по соображениям безопасности.
Но в любом случае даже глобальные символы, разрешаемые загрузчиком, имеют виртуальные адреса в адресном пространстве процесса.(Все это может быть неверно для встроенных устройств, но это обычно нет ничего, с чем вы столкнетесь при изучении C)
Я имею в виду, является ли это адрес, сгенерированный компилятором, то есть виртуальный адрес или загрузчик задал физический адрес в оперативной памяти.
Ложная дихотомия. Адрес, сгенерированный компилятором, перемещается компоновщиком, и именно этот адрес возвращается &. Это виртуальный адрес, если вы не работаете на чем-то странном, как NetWare 3, который не использует виртуальную машину.