为什么堆栈上对齐的整数之间有 8 个字节的"0xcc"填充?C++ 32位视窗7
Why is there 8 byte padding of "0xcc" between aligned ints on the stack? C++ 32 bit 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
我正在运行Windows 7 32位,使用Visual Studio 2010。没什么好说的了,但是stackoverflow不会让我在没有更多"细节"的情况下发布,所以这只是无用的漫谈:)
当你在Visual C中使用/GZ
选项编译代码时,所有未初始化的堆栈变量都使用0xcc
模式设置(我怀疑是为了帮助调试)。
因此,这些字节在那里可能是p
和i
整数(a),或使用int
作为指针的奇异的方法创建的临时值,您可能需要重新考虑。
在任何情况下,为什么在你的特定抽象层,c++"虚拟机"是无关紧要的。为了提高效率,一个实现可以自由地组织堆栈,在需要的地方插入填充。
(a)尽管i
是稍后在代码中声明的,但没有什么可以阻止安装在函数入口为它分配空间。下面发生的大多数事情都可能像这样令人惊讶,因为"as if"规则是控制实现如何工作的规则。只要效果符合标准,
0xcc来自于在调试构建中运行时。这样做是因为当您查找缓冲区溢出等错误时,可以很容易地识别此模式
它要么是填充,要么是未使用的临时变量。在带有调试版本的MSVC中,编译器生成代码用0xcc
字节填充所有变量。这有助于识别未使用的变量- cc
的选择不是随机选择,它有帮助,因为它是一个几乎不可能从操作系统中获得的地址,它也是int 3
指令,所以如果你突然找到执行该代码的方法(例如,指向数据某处的函数指针),代码将在那里停止。在调试了一些"失控代码"问题后,我发现这是一个非常有用的特性。
是一个相当大(或负数)的数字也是有益的,因为它经常显示"使用变量作为索引或指针",使它成为一个无效的访问,而不是,比如说,如果它是零,这将是一个有效的索引到一个数组,例如。
- 在c++中用vector填充一个简单的动态数组
- 如何使用用户输入在C++中正确填充2D数组
- 如何找到大小'x'数组是否完全填充,在C++?
- Cuda C++:设备上的Malloc类,并用来自主机的数据填充它
- 通过for循环使用用户输入填充列表
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 如何正确填充在堆上分配的二维数组?
- 将数字转换为填充字符串
- 有没有办法在一行中填充矢量图
- 用C++中的数字和条件填充向量
- 用真值填充矢量
- 使用结构成员指针在C++中填充结构
- 流填充字符的默认定位
- 使用不同算法的 PKCS1v15 填充进行加密 ++ 签名
- C++:使用缓冲区中的数据填充结构
- 如何将零填充的多维数组传递给 C++ 中的函数?
- Cryptopp:获取密码输入的填充字符串
- 填充上编译器生成的复制构造函数之间的不一致
- 控制未初始化堆栈变量的填充值(例如0xCC)
- 为什么堆栈上对齐的整数之间有 8 个字节的"0xcc"填充?C++ 32位视窗7