为什么堆栈上对齐的整数之间有 8 个字节的"0xcc"填充?C++ 32位视窗7

Why is there 8 byte padding of "0xcc" between aligned ints on the stack? C++ 32 bit Windows 7

本文关键字:填充 0xcc C++ 32位 对齐 堆栈 整数 之间 为什么 字节      更新时间:2023-10-16
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

我正在运行Windows 7 32位,使用Visual Studio 2010。没什么好说的了,但是stackoverflow不会让我在没有更多"细节"的情况下发布,所以这只是无用的漫谈:)

当你在Visual C中使用/GZ选项编译代码时,所有未初始化的堆栈变量都使用0xcc模式设置(我怀疑是为了帮助调试)。

因此,这些字节在那里可能是pi整数(a),或使用int作为指针的奇异的方法创建的临时值,您可能需要重新考虑。

在任何情况下,为什么在你的特定抽象层,c++"虚拟机"是无关紧要的。为了提高效率,一个实现可以自由地组织堆栈,在需要的地方插入填充。


(a)尽管i是稍后在代码中声明的,但没有什么可以阻止安装在函数入口为它分配空间。下面发生的大多数事情都可能像这样令人惊讶,因为"as if"规则是控制实现如何工作的规则。只要效果符合标准,

就可以做任何事情。

0xcc来自于在调试构建中运行时。这样做是因为当您查找缓冲区溢出等错误时,可以很容易地识别此模式

它要么是填充,要么是未使用的临时变量。在带有调试版本的MSVC中,编译器生成代码用0xcc字节填充所有变量。这有助于识别未使用的变量- cc的选择不是随机选择,它有帮助,因为它是一个几乎不可能从操作系统中获得的地址,它也是int 3指令,所以如果你突然找到执行该代码的方法(例如,指向数据某处的函数指针),代码将在那里停止。在调试了一些"失控代码"问题后,我发现这是一个非常有用的特性。

是一个相当大(或负数)的数字也是有益的,因为它经常显示"使用变量作为索引或指针",使它成为一个无效的访问,而不是,比如说,如果它是零,这将是一个有效的索引到一个数组,例如。