Указатели C ++, поведение операторов ++ - PullRequest
4 голосов
/ 04 июня 2019

Так что я где-то читал, что если у нас есть указатель p и некоторые значения i и j определены одно за другим, то эти значения в стеке будут одно за другим однако, по крайней мере, для меня это не так.

int i = 10;
int j = 20;
int *p = &i;
p++;
(*p) = 30;
std::cout << i << " " << j << " " << (*p) << "\n" ;

Вместо этого он напечатает эти значения 10 20 30 Если я прокомментирую, вместо (*p) = 30; внутри *p будет пустой адрес.

Я думал, что оператор ++ в этом случае изменит мою ссылку с i на j, а (*p) изменит значение j, но, очевидно, это не так.

Так что мне было интересно, что они имели в виду?

Ответы [ 4 ]

11 голосов
/ 04 июня 2019

Поведение вашего кода undefined .

Арифметика указателей действительна только для массивов. Вы не можете получить доступ к объекту, увеличив указатель на другой объект и разыменовав этот указатель. Чуть более подробно, определено p++ (объект может рассматриваться как массив из одного элемента, и вам разрешено устанавливать указатель на один за концом массива), но последующее разыменование не определено.

3 голосов
/ 04 июня 2019

Я думал, что оператор ++ в этом случае изменит мою ссылку с i на j и t ....

Это неправильно.Для этих определений:

int i = 10;
int j = 20;

Нет правила, которое позволяло бы хранить j в ячейке памяти рядом с i.

Более того, не путайте указатели (абстрактное понятие) с тем, что они моделируют (адрес физической памяти).Для большинства вещей хорошо думать об указателях как об адресах в физической памяти, однако, строго говоря, это не так.

Стандарт C ++ определяет определенные правила для указателей и то, что вы можете с ними делать.Увеличение указателя на int для получения указателя на другой int, определенный сразу после, не является одним из этих правил!Обратите внимание, что даже если в вашей аппаратной памяти два целых числа будут храниться в смежной памяти, при этом указатель по-прежнему будет увеличиваться до i, а затем разыменовываться, что это неопределенное поведение.

2 голосов
/ 04 июня 2019

Если вы хотите иметь смежные области памяти, вам нужно объявить массив. Поскольку ваш тип данных маленький, libc выделяет местоположения. Указатели занимают пробелы вокруг объявленных переменных.

2 голосов
/ 04 июня 2019

Оператор ++ будет указывать на следующее место в памяти, а не на следующую переменную.

Если у вас будет int i[2] = {10, 20};, то p++ будет указывать на i[1], т.е. 20

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