C++ Что происходит с исходным адресом памяти переменной, когда она присваивается указателю?

Я пытаюсь разобраться в деталях использования указателей и ссылок.

Здесь я оставил несколько комментариев, которые могут показать ход моих мыслей:

using namespace std;
#include <iostream>

int main()
{
    int ref; // A variable at an unknown memory address (lets call the address X)
    int *point; // An empty memory address (lets call the address Y)

        ref = 3; // An int 3 is stored at address X
        point = &ref; // Address Y now contains 'ref'

        //What happened to address X? Are there two addresses now, known and unknown?

    cout << point << endl;  //prints address Y
    cout << *point << endl; //prints address Y contents (3)
    cout << ref << endl; //prints 3 from ?
    
    return 0;
}

Попробуйте следующее: cout << ref << " " << (void *) (&ref) << endl; -- выведите адрес переменной ref.

Thomas Matthews 29.07.2024 21:03

У вас может быть 5 разных вещей, указывающих на X (адрес ссылки), и все равно останется только 1 X. Присвоение point = &ref не меняет X, оно просто дает вам второй способ чтения или записи в тот же X, который вы создали. объявив int ref.

Dave S 29.07.2024 21:07

Меня смущает то, что вы думаете о адресе Y (и я думаю, что вы тоже). Вы сказали: «//Адрес Y теперь содержит «ref». Это неправда, лучше было бы сказать, что переменная-указатель point теперь содержит адрес X. '// печатает адрес Y', нет, она печатает адрес X. 'cout << *point << endl; // печатает содержимое адреса Y (3)'` нет, печатает содержимое адреса X.

john 29.07.2024 21:11

Одной из распространенных причин путаницы является неправильное представление о переменных-указателях. Вера в то, что они особенные и к ним применяются другие правила по сравнению с обычными переменными. Кажется, у вас есть некоторая разновидность этого убеждения, но это неправда, переменные-указатели — это всего лишь обычные переменные. Они могут иметь значения (или не иметь), и им можно присваивать значения; при присвоении они теряют свое предыдущее значение, как и обычные переменные.

john 29.07.2024 21:15

@DaveS Скопируйте это — теперь это имеет смысл, спасибо!

Code N00b 29.07.2024 21:27

Примечание: ничто в этом коде не требует дополнительных вещей, которые делает std::endl; используйте '\n', чтобы завершить строку, если у вас нет веской причины не делать этого.

Pete Becker 29.07.2024 21:34

Чтобы еще больше вас запутать: компилятору разрешено помещать переменные в регистры, чтобы не было использования памяти.

Thomas Matthews 29.07.2024 21:35

«Что случилось с адресом X?» -- Я не слежу за этим вопросом. Почему что-то должно случиться с X только потому, что вы прямо не упомянули об этом в предыдущей строке? Почему «int 3 хранится по адресу X» не может быть правдой?

JaMiT 30.07.2024 01:40
An empty memory address (lets call the address Y) должно читаться A variable at an unknown memory address (lets call the address Y), а Address Y now contains 'ref' должно быть Address Y now contains address X
M.M 30.07.2024 01:55
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
9
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Линия:

cout << ref << endl;

печатает 3 из памяти, выделенной для переменной ref, которая в вашей терминологии находится по адресу памяти X. На самом деле он выделяется в автоматическом хранилище (обычно в стеке) и имеет время жизни переменной ref, которая является телом функции main.

Ничего не могло произойти именно «по адресу X», именно значение, которое хранится по «адресу X», было инициализировано (имело какое-то случайное значение) и позже ему было присвоено значение 3. То же самое произошло и с указателем Y, он содержал некоторый начальный случайный адрес, а затем был установлен на X.

Таким образом, по сути, в памяти есть два места, которые обновляются при изменении ref с этого момента... Скажем ref = 7; //Two memory addresses updated: X (unknown) and Y (known)?

Code N00b 29.07.2024 21:04

Нет. Обновляется только 1 переменная. point указывает на то же место 1, где ref хранит свое значение.

drescherjm 29.07.2024 21:05

Ааа, кажется, я понимаю... Итак, point = &ref; получил (ранее неизвестный) адрес памяти ref? Если это верно, то что было point до того, как оно указывало на ref? Просто пустой адрес, который однажды теряется point, на самом деле указывает?

Code N00b 29.07.2024 21:09

Значение @CodeN00b point до присвоения было неопределенным. Могло быть что угодно, и это очень взрывоопасное состояние. В общем, лучше не иметь инициализированную переменную там, где ее может найти ребенок, поэтому избегайте определения переменной до того, как вы узнаете, какое ее значение будет. Например: int *point = &ref;

user4581301 29.07.2024 21:12

Понятно, звучит устрашающе :'D Спасибо вам обоим!

Code N00b 29.07.2024 21:17

Два комментария выше: отсутствие инициализированной переменной должно было означать отсутствие неинициализированной переменной. Извините за это.

user4581301 29.07.2024 21:19

@CodeN00b, ты прав; обновил ответ.

Damir Tenishev 29.07.2024 22:53

Другие вопросы по теме