C ++ / Адресное пространство: 2 байта на адрес? - PullRequest
0 голосов
/ 11 сентября 2018

Я просто что-то пробовал, и мне было интересно, как это могло быть.У меня есть следующий код:

int var1 = 132;

int var2 = 200;

int *secondvariable = &var2;

cout << *(secondvariable+2) << endl << sizeof(int) << endl;

Я получаю вывод

132

4

Так как это возможно, что второй int только2 адреса выше?Я имею в виду не должно быть 4 адреса?Я в настоящее время под WIN10 x64.

С уважением

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

В то время как вы уже находитесь в области неопределенного поведения (см. Некоторые программисты чувак ' ответ ) из-за индексации массива вне границ (одна переменная считается массив длины 1 для таких вопросов), некоторые технические знания:

Выравнивание! Компиляторам разрешено размещать переменные по адресам так, чтобы к ним можно было обращаться наиболее эффективно. Поскольку вы , кажется, получили действительный вывод, добавив 2*sizeof(int) к адресу второй переменной, вы, очевидно, достигли первого случайно . По-видимому, компилятор решил оставить пробел между двумя переменными, чтобы обе можно было выровнять по адресам, кратным 8.

Имейте в виду, однако, что у вас нет никакой гарантии для такого выравнивания, разные компиляторы могут решить по-разному (или один и тот же компилятор в другой системе), и выравнивание даже может быть изменено с помощью флагов компилятора.

С другой стороны, массивы гарантированно занимают непрерывную память, поэтому вы могли бы получить ожидаемый результат в следующем примере:

int array[2];

int* a0 = &array[0];
int* a1 = &array[1];

uintptr_t diff = static_cast<uintptr_t>(a1) - static_cast<uintptr_t>(a0);
std::cout << diff;

Приведение к uintptr_t (или к char*) обеспечивает получение разницы адресов в байтах, а не в размерах int ...

0 голосов
/ 11 сентября 2018

Это не так, как работает C ++.

Вы не можете "перемещаться" по своей области следующим образом.

Такие действия над указателями имеют совершенно неопределенное поведение и на них нельзя полагаться.

Вы не пробиваете дыры в ленте, вы пишете описание семантики программы, которая преобразуется вашим компилятором во что-то исполняемое на машине.

Кодируйте эти абстракции, и все будетхорошо.

0 голосов
/ 11 сентября 2018

С cout << *(secondvariable+2) вы не печатаете указатель, вы печатаете значение в secondvariable[2], что является неверным индексированием и приводит к неопределенному поведению .

Если вы хотите напечатать указатель, отбросьте разыменование и напечатайте secondvariable+2.

...