Указатели C / C ++, ptr + 1 = ptr +1 байт или ptr + 1 * sizeof (pointer_type)? - PullRequest
3 голосов
/ 24 января 2011

Имея

any_type *ptr = (any_type*)malloc(sizeof(any_type)*size);
my_ptr = ptr+1;
memcpy(dst, my_ptr, sizeof(any_type));

Будет ли my_ptr указывать на 1 байт после ptr или sizeof(any_type) байт после ptr? Как параметры выравнивания могут повлиять на ответ? Отличается ли для подписанных / неподписанных типов?

Ответы [ 5 ]

11 голосов
/ 24 января 2011

Арифметика указателя выполняется по размеру статического типа [*] указателя, поэтому он будет эффективно добавлять sizeof *ptr. Выравнивание элементов будет учитываться по размеру объекта как выравнивание типа (заполнение в конце объекта).

struct test {
   int a;
   char b;
};

Размер test не будет равен 5 (при условии 32-битных значений), если тип выровнен по 4 байта.

[*] Обратите внимание, что в C ++ вы можете назначить адрес производного объекта базовому классу, но арифметика указателей будет работать с типом указателя , а не с реальными объектами:

struct base { int x; };
struct derived : base { int y; };
int main() {
   base * p = new derived[10];
   base * q = p+1;             // this does not point to the second `derived`!!!
}
4 голосов
/ 24 января 2011

Компилятор заменит это 1 на соответствующее количество байтов. Все, что вам нужно сделать, это указать количество объектов , к которым вы хотите перейти.

4 голосов
/ 24 января 2011
  1. sizeof (any_type) после ptr
  2. malloc возвращает память, подходящую для выравнивания данных любого типа
  3. без разницы между знаком / без знака
2 голосов
/ 24 января 2011

Когда вы видите указатель, постарайтесь забыть, что он имеет скалярное значение.Вместо этого подумайте, что указатель является своего рода токеном, который дает вам доступ к объекту, который хранится в непрерывном пространстве (памяти).Если ptr является указателем, который дает вам доступ к объекту в некоторой (произвольной) позиции, ptr+1 и ptr-1 будут возвращать указатели, которые дают вам доступ к его соседям.

1 голос
/ 24 января 2011

Чтобы арифметика указателя работала, она должна указывать на sizeof (any_type) + базовый адрес.

...