Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 242

Разные адреса одной и той же переменной. Почему?

02.02.2019, 01:21. Показов 2248. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот сам наткнулся на такую вещь.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int * GETAdress(int tmp)
{   return &tmp;    }
 
int main()
{
    int  a  =  6;
    int *pa;
 
    pa = GETAdress(a);
    cout << "Fun: " << GETAdress(a) << endl;
    cout << "pa:  " << pa << endl;
    cout << "&a:  " << &a << endl;
 
    _getch();
    return 0;
}
Вывод:
Fun: 00F9F9F0
pa: 00F9F9F4
&a: 00F9FAD4

Почему когда я присваиваю pa возвращаемое значение(адрес) функции, то адрес один присваивается. А когда вызываю отдельно функцию(передаю всё те же пар-ры), то адрес отличается. Потом вывожу адрес самой переменной a - адрес опять отличается!
Думал, может из-за того, что при каждом новом вызове функции, создается новая переменная и соответственно, новый адрес. Но, нет. Подряд вызывал саму функцию - всё одно и то же.

Даже пытался изменять значения, по отличаемым адресам, значения менялись везде. Такое ощущение, что создается указатель на указатель и так много раз. Как это вообще работает???

PS: скорее всего это из-за функции, так как где то читал, что туда копируется то что мы передаем, а значит и где то хранится, а значит и адрес новый...Но всё как то запутано для меня...

Буду благодарен за развернутый ответ!)
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
02.02.2019, 01:21
Ответы с готовыми решениями:

Два адреса одной и той же страницы
Просматривая ошибки в Google админ увидел повторяющиеся одинаковый тайтл &lt;div&gt;CODE&lt;/div&gt;&lt;div&gt;Повторяющийся тайтл ? ...

Адреса одной и той же страницы с index.php
Здравствуйте. Расскажите пожалуйста, считаются ли вашсайт.ru и вашсайт.ru/index.php разными страницами с идентичным контентом? Спасибо.

Разные фоны блоков на одной и той же странице
Добрый день, прописываю на странице код: &lt;div style=&quot;background-color: #c9c;&quot;&gt;текст&lt;/div&gt;, но у меня задник растягивается только под...

5
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
02.02.2019, 01:57
GETAdress возвращает адрес своего аргумента, который копируется.

Вам стоит передавать аргумент по ссылке.
C++
1
2
int * GETAdress(int& tmp)
{   return &tmp;    }
Добавлено через 2 минуты
Fun: 0x7ffdcb302c74
pa: 0x7ffdcb302c74
&a: 0x7ffdcb302c74
Вот результаты теста.

Суть в том, что Вы передали параметр по значению и он скопировался. То есть, у Вас tmp — уже другая переменная, а не a.
1
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 242
02.02.2019, 02:17  [ТС]
New man, за ссылки я знаю, то понятно. "То есть, у Вас tmp — уже другая переменная, а не a." - хмм, об этом я не задумывался, спасибо. Но тогда почему меняя по любому из трех адресов что-то(например *pa = 23), меняется всё везде?
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
02.02.2019, 02:35
Лучший ответ Сообщение было отмечено MJ_PRUTYG как решение

Решение

Смотрите по порядку. Это очень упрощённое объяснение, в реальности всё может быть иначе из-за оптимизаций компилятора.
Вообще, стандарт не гарантирует, в каком порядке компилятор уложит локальные переменные.

Вы выделили память на стеке под переменную a.
&a == 00F9FAD4
Следовательно, указатель на свободный адрес на стеке сместился на размер int.

Потом Вы выделили на стеке место под переменную pa, указатель стека сместился ещё.
И вот уже в этот адрес скопировался аргумент функции и его вернула функция.

Потом Вы положили на стек результат вызова cout << "Fun: ", а именно, ссылку на объект std::cout. Потом повторилась ситуация с предыдущим вызовом функции, но состояние стека было уже другим, поэтому и параметр скопировался в другое место.

В случае же передачи параметра по ссылке, адрес a вычисляется ещё до вызова, так как в машинном коде ссылки обрабатываются как указатели.

Добавлено через 4 минуты
Влияние оптимизаций на вычисление:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int * GETAdress(int tmp)
{   return &tmp;    }
 
int main()
{
    using namespace std;
    int  a  =  6;
    cout << GETAdress(a) << endl;
    cout << GETAdress(a) << endl;
    return 0;
}
При компиляции компилятором clang без оптимизаций (-O0) вывело:
0x7ffde5fe52dc
0x7ffde5fe52dc
С оптимизацией (-O2):
0x7ffebfbb9400
0x7ffebfbb9404
1
3 / 3 / 0
Регистрация: 28.11.2018
Сообщений: 242
02.02.2019, 02:48  [ТС]
New man, ааа, я понял, это довольно многое объясняет. Спасибо большое! Только один момент. Почему у меня заполняется стек в обратную сторону? Имею ввиду что...Например у вас идет 0x7ffebfbb9400, а потом 0х...404. А у меня сначала второе, потом первое. Как будто с конца? Так же быть не должно, неправда ли? Или я что-то упускаю?(тот же код)
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
02.02.2019, 03:05
Конкретный порядок роста стека определяется платформой.
C++ при компиляции вообще по особому отрабатывает это дело.

Смотри код:
C++
1
2
3
int arr[10];
int* begin = &arr[0];
int* end = &arr[10];
Так вот, в численном виде указатель end может оказаться как меньше, так и больше begin. Но C++ гарантирует, что оператор сравнения указателей на уровне C++ всегда будет возращать true для выражения begin<end.

Добавлено через 2 минуты
То есть, он просто меняет операцию на противоположную при компиляции на платформу, где Int(begin)>Int(end).
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
02.02.2019, 03:05
Помогаю со студенческими работами здесь

Разные ошибки в одной и той же программе с разными IDE
Добрый день. Столкнулся с проблемой. Начинал писать в Ubuntu используя QtCreator. Компилятор GCC. Все работало. Потом исходники перенес...

Разные драйверы под разное железо на одной и той же системе Windows
Можно ли установить в системе драйвера под разные типы железа и по необходимости выбирать&quot; нужный pack драйверов? Не будут ли они...

Как вывести наибольшее число из одной и той же переменной?
Дано натуральное число N. Получить наибольшее число вида 4k , меньшее N. Результат вывести на экран и записать в файл. class Program ...

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

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru