переменные — почему существует 8-байтовое заполнение & quot; 0xcc & quot; между выровненными целыми числами в стеке? C ++ 32-битная Windows 7

int p;
int i1;
int i2;
i1 = 1 << 16;
i2 = 1 << 8;
p = int(&i1)+3;

cout << hex;
cout << "&i1: " << int(&i1) << endl;
cout << "&i2: " << int(&i2) << endl;
for(int i = 0; i < 16; i++)
cout << p << ": " << uint(*((byte*)p--)) << endl;

Выход:

&i1: 12fac8
&i2: 12fabc
12facb: 0
12faca: 1
12fac9: 0
12fac8: 0
12fac7: cc
12fac6: cc
12fac5: cc
12fac4: cc
12fac3: cc
12fac2: cc
12fac1: cc
12fac0: cc
12fabf: 0
12fabe: 0
12fabd: 1
12fabc: 0

Я использую 32-битную Windows 7, использую Visual Studio 2010. Больше нечего сказать, но stackoverflow не позволит мне публиковать без дополнительных «подробностей», так что это просто бесполезная болтовня 🙂

2

Решение

Когда вы компилируете код в Visual C с /GZ опция, все неинициализированные переменные стека устанавливаются с помощью 0xcc шаблон (чтобы помочь отладке, я подозреваю).

Следовательно, эти байты, вероятно, p а также i целые (А), или временные, созданные эксцентричный метод использования int как указатель, то, что вы можете переосмыслить.

В любом случае, Зачем они там не имеют значения на вашем конкретном уровне абстракции, C ++ «виртуальная машина». Реализация свободна организовать стек так, как она хочет для эффективности, вставляя отступ там, где это необходимо.


(А) Несмотря на i позже объявлено в коде, ничто не мешает установке выделить пространство для него при входе в функцию. Большинство вещей, происходящих под прикрытием, могут удивлять, как это, так как правило «как будто» определяет, как работает реализация. Он может делать все, что захочет, при условии эффект соответствует тому, что в стандарте.

3

Другие решения

0xcc появляется при запуске в отладочной сборке. Это сделано потому, что вы можете легко распознать этот шаблон, когда вы ищете ошибки для переполнения буфера и т. Д.

1

Это либо заполнение, либо неиспользуемые временные переменные. В MSVC с отладочными сборками компилятор генерирует код для заполнения всех переменных 0xcc байт. Это помогает идентифицировать неиспользуемые переменные — и выбор cc это не случайный выбор, это помогает, потому что это почти невозможно получить адрес от ОС, и это также int 3 инструкции, поэтому, если вы вдруг найдете способ выполнить этот код (например, указатель на функцию где-то в данных), код будет остановлен тут же. Отладив несколько проблем с «убегающим кодом», я нахожу это очень полезной функцией.

Тот факт, что это довольно высокое (или отрицательное) число, также полезен, поскольку он часто демонстрирует «использование переменной в качестве индекса или указателя», делая ее недопустимым доступом, а не, скажем, если бы это был ноль, который был бы допустимый индекс в массив, например.

1
По вопросам рекламы [email protected]