Адрес (&) дает сгенерированный компилятором адрес или адрес сгенерированный загрузчиком? - PullRequest
4 голосов
/ 08 марта 2012
int a;
printf("address is %u", &a);

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

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

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

Ответы [ 4 ]

4 голосов
/ 08 марта 2012

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

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

3 голосов
/ 08 марта 2012

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

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

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

2 голосов
/ 08 марта 2012

Правильный ответ: «это зависит».

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

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

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

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

0 голосов
/ 09 марта 2012

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

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

...