c ++ указатель и переменный адрес переключения значения, почему? - PullRequest
0 голосов
/ 06 ноября 2019

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

Вот код:

int *ret;
int set = 56;

ret = (int *)&ret - 1;
*ret = 3;

cout << ret << endl << &set << endl << set <<endl;

Вывод:

0x61ff08
0x61ff08
3

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

cout << ret << endl << &set << endl << set <<endl;

На это:

cout << ret << endl << set <<endl;

вывод становится:

0x61ff04
56

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

Если я это сделал:

ret = (int *)&ret + 1; // instead of -1

Выходстановится:

0x61ff0c
3

Могу ли я получить объяснение? Я не нашел никаких документов по этому поводу.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Могу ли я получить объяснение? Я не нашел никакой документации по этому поводу.

Основная документация в этом случае является стандартом C ++, хотя иногда бывает нелегко найти и понять информацию оттуда. Итак, короткая версия в вашем случае - вы можете вычитать или добавлять целые числа к указателю только тогда, когда результирующий указатель будет указывать на элемент в том же массиве или указывать на фиктивный элемент за последним (в этом случае разыменование указателя недопустимо),Для этой цели отдельная переменная обрабатывается как массив одного элемента (поэтому для указателя на одну переменную вы в основном можете сделать только pointer + 1). Все другие хакерские попытки получить доступ к переменным с помощью магии с арифметикой указателей являются недопустимыми и приводят к неопределенному поведению .

Подробную информацию о UB вы можете найти здесь Что именно делают "IB" и "UB "значит?

0 голосов
/ 06 ноября 2019

Ответ состоял в том, что компилятор дает свой адрес переменной / указателям в соответствии с кодом, чтобы адреса могли меняться, чтобы решить эту проблему, используя только адреса

вместо: ret = (int *)&ret - 1;

мы можем использовать: ret = (int *)ret - ((int)(ret - &set));

(я не хотел использовать базовый ret = &set, потому что я пытался сделать это, манипулируя только адресами)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...