В чем разница между сохраненным и отображаемым адресом на C и С++?

В C, если я делаю переменную и печатаю ее адрес следующим образом:

int a;
int main (void) {
    printf ("%p", &a);
    return 0;
}

Результат: 00AA

То же самое в С++ с использованием строки:

cout << &a << endl;

Выход был: 0x8f970aa

В чем разница между этими двумя?

Я скомпилировал обе программы с помощью Turbo C.

Ответ 1

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

Это не имеет ничего общего с C и С++. В обоих стандартах указано, что ваша переменная должна быть распределена со статической продолжительностью хранения. Все переменные статической продолжительности хранения, которые явно не инициализируются, гарантируются стандартами C и С++ для инициализации до нуля (см., Например, C11 6.7.9/10).

Это означает, что оба стандарта косвенно гарантируют выделение переменной в .bss. Точно, где в .bss не указывается нигде.

Связанный с этим вопрос.

Ответ 2

Это сравнение бессмысленно, потому что C и С++ - разные языки. Также вы можете получать разные результаты при каждом запуске своего кода для одного и того же языка на одном компьютере с использованием того же самого компилятора. Нет необходимости, чтобы память для переменной a была выделена в том же месте. Результатом является реализация.

C11: 7.21.6 (p8):

p Аргумент должен быть указателем на void. Значение указателя преобразуется в последовательность символов печати в соответствии с реализацией.

Ответ 3

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

int a;

int main (void) {

printf ("%p\n", &a);
cout << &a << endl;

return 0;
}

Адрес будет таким же, который в конце концов, все, что имеет значение!

Код С++ вытаскивает больше библиотек и запускает код и статические данные по умолчанию С++ (cout, cerr, cin и т.д.), чем код C. Таким образом, адрес может попасть в память выше. Также начальный адрес приложения может быть установлен по-разному для C и С++ или даже случайным. В настройках Visual С++ у вас может быть "Рандомизированный базовый адрес" или "Фиксированный базовый адрес". Эти настройки будут перемещать int адрес.

Ответ 4

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