Увеличение указателя в C ++ - PullRequest
5 голосов
/ 27 июня 2011

Что это значит: приращение указателя указывает на адрес следующего базового типа указателя?
Например:

p1++;  // p1 is a pointer to an int

Означает ли это утверждение, что адрес, на который указывает p1, должен измениться на адрес следующего int или его следует просто увеличить на 2 (при условии, что int равен 2 байта), в этом случае конкретный адрес не может содержать int?
Я имею в виду, если p1, скажем, 0x442012, будет p1++ быть 0x442014 (который может быть частью адреса типа double) или он будет указывать на следующий int, который находится в адресе, подобном 0x44201F?

Спасибо

Ответы [ 5 ]

10 голосов
/ 27 июня 2011

Арифметика указателей не заботится о содержании - или действительности - указателя. Он просто увеличит адрес указателя по следующей формуле:

new_value = reinterpret_cast<char*>(p) + sizeof(*p);

(Предполагается, что указатель не на const - иначе приведение не сработает.)

То есть он будет увеличивать указатель на величину sizeof(*p) байтов, независимо от таких вещей, как значение pointee и выравнивание памяти.

4 голосов
/ 27 июня 2011

Компилятор добавит sizeof(int) (обычно 4) к числовому значению указателя.Если p1 равен 0x442012 до приращения, то после приращения оно будет 0x442012 + 4 = 0x442016.

Имейте в виду, 0x442012 не кратно 4, поэтому вряд ли это будет адрес действительной четверки-byte int, хотя для ваших двухбайтовых целых это будет хорошо.

Конечно, оно не пойдет в поисках следующего целого числа.Это потребует магии.

3 голосов
/ 27 июня 2011

p1 ++ приводит к появлению инструкций на ассемблере, которые увеличивают p1 на размер, на который он указывает.Таким образом, вы получаете

(char *)p1 = (char *)p1 + sizeof (object pointed to by p1)

(когда на этот вопрос был дан ответ) Обычно int равен 4 байта, поэтому он будет увеличиваться на 4, но это зависит от sizeof () на вашем компьютере..

Он не переходит к «следующему целому».

Пример: предположим, что 4-байтовый адрес и p1 = 0x20424 (где p1 - int *),Тогда

p1++

установит новое значение p1 в 0x20428.НЕ 0x20425.

1 голос
/ 28 января 2017

Если p1 указывает на элемент индекса n массива объектов типа int (объект без массива считается для этой цели массивом длины 1), то после p1++ , p1 это либо:

  • Указывает на элемент индекса n+1, если длина массива превышает n+1.
  • Адрес массива в конце, если длина массива точно равна n+1.

p1++ вызывает неопределенное поведение, если p1 не указывает на элемент массива объектов типа int.

Единственное значение, которое языки C и C ++ придают понятию «адрес», - это значение объекта указателя.

Любое отношение, которое понятие адреса в C / C ++ имеет к понятию числовых адресов, которое вы рассматриваете на ассемблере, является чисто деталями реализации (хотя и очень распространенными деталями реализации).

0 голосов
/ 27 июня 2011

Арифметика указателя выполняется в sizoeof(*pointer) кратных, то есть для указателя на int приращение будет переходить к следующему целому числу (или 4 байта для 32-разрядных целых чисел).

...