Ответ 1
Стандартные состояния С++ в разделе 8.3.4 Массивы, которые: "Объект типа массива содержит смежно выделенный непустой набор из N подобъектов типа T".
Вот почему array[]
будет множеством смежных int
, и эта разница между одним элементом и следующим будет точно sizeof (int).
Для локальных/блочных переменных (автоматическое хранение) такая гарантия не предоставляется. Единственные утверждения приведены в разделе 1.7. Модель памяти С++: "Каждый байт имеет уникальный адрес". и 1.8. Объектная модель С++: "адрес этого объекта - это адрес первого байта, который он занимает. Два объекта (...) должны иметь разные адреса".
Итак, все, что вы делаете, предполагая смежность таких объектов, будет undefined поведение и не переносится. Вы даже не можете быть уверены в порядке адресов, в которых эти объекты создаются.
Теперь я играл с измененной версией вашего кода:
int a = 10, b = 20, c = 30, d = 40; //consecutive 4 int data values.
int* p = &d; //address of variable d.
int array[] = { 10, 20, 30, 40 };
char *pa = reinterpret_cast<char*>(&a),
*pb = reinterpret_cast<char*>(&b),
*pc = reinterpret_cast<char*>(&c),
*pd = reinterpret_cast<char*>(&d);
cout << "sizeof(int)=" << sizeof(int) << "\n &a=" << &a << \
" +" << pa - pb << "char\n &b=" << &b << \
" +" << pb - pc << "char\n &c=" << &c << \
" +" << pc - pd << "char\n &d=" << &d;
memset(&d, 0, (&a - &d)*sizeof(int));
// ATTENTION: undefined behaviour:
// will trigger core dump on leaving
// "Runtime check #2, stack arround the variable b was corrupted".
При запуске этого кода я получаю:
debug release comment on release
sizeof(int)=4 sizeof(int)=4
&a=0052F884 +12char &a=009EF9AC +4char
&b=0052F878 +12char &b=009EF9A8 +-8char // is before a
&c=0052F86C +12char &c=009EF9B0 +12char // is just after a !!
&d=0052F860 &d=009EF9A4
Итак, вы видите, что порядок адресов может быть даже изменен в одном и том же компиляторе, в зависимости от настроек сборки! Фактически, в режиме выпуска переменные смежны, но не в том же порядке.
Дополнительные пробелы в отладочной версии исходят из опции /RTCs. Я специально переписал переменные жестким memset(), который предполагает, что они смежны. При выходе из выполнения я сразу получаю сообщение: "Проверка выполнения # 2, стек arround, переменная b была повреждена", что наглядно демонстрирует цель этих дополнительных символов.
Если вы удалите этот параметр, вы получите с непрерывными переменными MSVC13, каждый из 4 байтов, как вы ожидали. Но больше не будет сообщений об ошибках в коррупции стека.