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

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

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

Author24 — интернет-сервис помощи студентам
Вот сам наткнулся на такую вещь.
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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.02.2019, 01:21
Ответы с готовыми решениями:

Два адреса одной и той же страницы
Просматривая ошибки в Google админ увидел повторяющиеся одинаковый тайтл ...

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

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

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

5
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
02.02.2019, 01:57 2
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  [ТС] 3
New man, за ссылки я знаю, то понятно. "То есть, у Вас tmp — уже другая переменная, а не a." - хмм, об этом я не задумывался, спасибо. Но тогда почему меняя по любому из трех адресов что-то(например *pa = 23), меняется всё везде?
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
02.02.2019, 02:35 4
Лучший ответ Сообщение было отмечено 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  [ТС] 5
New man, ааа, я понял, это довольно многое объясняет. Спасибо большое! Только один момент. Почему у меня заполняется стек в обратную сторону? Имею ввиду что...Например у вас идет 0x7ffebfbb9400, а потом 0х...404. А у меня сначала второе, потом первое. Как будто с конца? Так же быть не должно, неправда ли? Или я что-то упускаю?(тот же код)
0
309 / 221 / 74
Регистрация: 23.05.2011
Сообщений: 981
02.02.2019, 03:05 6
Конкретный порядок роста стека определяется платформой.
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
02.02.2019, 03:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.02.2019, 03:05
Помогаю со студенческими работами здесь

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

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

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

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

Разные значение одной переменной
Не буду вдаваться в подробности, покажу саму проблему: есть код while not eof(f) do begin ...

Можно ли задать для одной и той же переменной сразу несколько значений
Krasme, я даже не знаю,в тему ли будет,в общем поправьте тогда,если что. Можно ли в маткаде задать...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru