Указатель математика против индекса массива - PullRequest
11 голосов
/ 19 августа 2011

Я знаю, что это хэшируется много раз, но сегодня я столкнулся с случаем, который потряс мое понимание математики указателя / индекса массива.

Как я всегда это понимал, & mybuff [10] и (& mybuff + 10) являются эквивалентными способами обращения к одной и той же памяти.

Однако я провел утро, борясь со случаем, когда:

memcpy(&mybuff+10,&in,8); 

переполнял буфер при компиляции с оптимизацией и работал очень хорошо при компиляции для отладки.

В то же время,

memcpy(&mybuff[10],&in,8); 

отлично работал в обоих случаях.

Большое спасибо за любые идеи или указатели.

Ответы [ 7 ]

7 голосов
/ 19 августа 2011

Я придумаю объявление для mybuff для примера:

char mybuff[123];

Теперь &mybuff+10 делает арифмический указатель на &mybuff, который имеет указатель типа "на массив"из 123 символов ".Это отличается от простого mybuff, который (после затухания указателя) имеет тип "pointer to char".Битовые значения этих двух выражений одинаковы, но поскольку они являются указателями на объекты разных размеров, они ведут себя по-разному в арифметике указателей.

&mybuff+10 означает, что вы хотите пройти десятую из 123-Массивы char в типе (что бессмысленно с учетом объявления и может привести к сбою), тогда как mybuff+10 просто говорит, что вы хотите пройти десять отдельных символов.

7 голосов
/ 19 августа 2011

см. http://cplusplus.com/doc/tutorial/operators/ для определения приоритета операторов
&mybuff+10 как (&mybuff)+10
&mybuff[10] как &(mybuff[10])

Редактировать
также некоторые указатели http://cplusplus.com/doc/tutorial/pointers/

4 голосов
/ 19 августа 2011

&mybuff[10] эквивалентно &mybuff[0] + 10, что эквивалентно mybuff + 10

Индексация массива определяется в терминах арифметики указателей. p[i] означает *(p+i) (я игнорирую необходимость в дополнительных скобках в случае, если p или i - более сложное выражение), где p - значение указателя, а i - целочисленное значение.

Общая информация: Поскольку сложение, даже указатель + сложение целых чисел, является коммутативным, p[i] также можно записать как i[p]. Да, 4["Hello"] == 'o'. Ради тех, кто читает ваш код в будущем, пожалуйста, , а не используйте эти знания.

Отличная ссылка на отношения между массивами и указателями в C (и C ++, где правила почти идентичны) - это раздел 6 comp.lang.c FAQ . (Я мог бы связать непосредственно с разделом 6, но я хотел бы призвать людей просматривать его; все это стоит прочитать.)

2 голосов
/ 19 августа 2011

(&mybuff+10) и &mybuff[10] являются не эквивалентными, но &mybuff[10] и mybuff + 10 являются.

2 голосов
/ 19 августа 2011

Я думаю, у вас проблемы с указателем.Если mybuff является указателем, то mybuff + 10 == &(mybuff[10]).Это не то же самое, что &mybuff + 10, как у вас там.

1 голос
/ 19 августа 2011

Причина, по которой он работал в режиме отладки, заключается в том, что в режиме отладки память инициализируется для вас, и выделения также превышают фактический размер.http://msdn.microsoft.com/en-us/library/bebs9zyz(v=vs.80).aspx

1 голос
/ 19 августа 2011

Правильный синтаксис: mybuff+10, а не &mybuff+10, который говорит о перемещении на позицию 10 в вашем массиве и копировании 8 байтов (согласно вашему выражению memcpy). Тем не менее, пока неизвестно, можете ли вы на самом деле удерживать дополнительные 8 байтов.

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