#include <windows.h> char x; short y; int check() { x =1; y=2; return 0; } int main(int argc, char* argv[]) { check(); system("pause"); return 0; } //上述代码中 check 函数的反汇编 13: x =1; 00401038 C6 05 E2 55 42 00 01 mov byte ptr [x (004255e2)],1 14: y=2; 0040103F 66 C7 05 E0 55 42 00 mov word ptr [y (004255e0)],offset check+26h (00401046) //下面将y的类型改为 int #include <windows.h> char x; int y; int check() { x =1; y=2; return 0; } int main(int argc, char* argv[]) { check(); system("pause"); return 0; } //上述代码中 check 函数的反汇编 13: x =1; 00401038 C6 05 E4 55 42 00 01 mov byte ptr [x (004255e4)],1 14: y=2; 0040103F C7 05 E0 55 42 00 02 mov dword ptr [y (004255e0)],2
我们发现,x跟y都是全局变量,但是它们的地址却不不是连续的.
字节对齐就是一个变量内存开始的地址,一定是当前变量宽度的整数倍,
字节对齐的目的是为了提升程序查找数据、读写数据的速度。用空间换时间
结构体 内存起始地址一定是结构体内成员最宽的宽度的整数倍
结构体内部的成员也遵守字节对齐,但是可以通过下面的方法改变
sizeof的使用,sizeof 可以输出当前类型的宽度
什么是字节对齐
char x; short y; int z;
字节对齐:
一个变量占用n个字节,则该变量的起始地址必须是 n 的整数倍,
即:存放起始地址 % n =0
如果是结构体,那么结构体的起始地址是其最宽数据类型成员的整数倍
结构体中的成员也遵守字节对齐
struct Test { char a; int b; } struct Test2 { int a; __int64 n; } ————int64 //vc6中支持的8字节整型
结构体的起始位置,是遵守字节对齐的。
Test 结构体的起始位置 一定是 4 的整数倍
Test2 结构体的起始位置 一定是 8 的整数倍
验证:
#include <stdio.h> #include <windows.h> struct Test1 { char a; int b; }; struct Test2 { int a; __int64 b; }; int check() { printf("%d %d /n",sizeof(Test1),sizeof(Test2)); return 0; } int main(int argc, char* argv[]) { check(); system("pause"); return 0; } //上述代码结果 8 16
改变编译器自动字节对齐方式
当对空间要求较高的时候,可以通过#pragma pack(n)
来改变结构体成员的对齐方式
#pragma pack(1) struct Test{ char a; int b; } #pragma pack()
#pragma pack(n)
中n用来设定变量以n字节对齐方式,可以设定的值包含 :1、2、4、8,vc编译器默认8- 若需取消强制对齐方式,则可以用命令
#pragma pack()
结构体总大小:N = min(最大成员,对齐参数)
结构体最后一个元素的宽度是 N的整数倍
验证
#include <stdio.h> #include <windows.h> #pragma pack(1) struct Test1 { char a; int b; }; struct Test2 { int a; __int64 b; }; #pragma pack() int check() { printf("%d %d /n",sizeof(Test1),sizeof(Test2)); return 0; } int main(int argc, char* argv[]) { check(); system("pause"); return 0; } //此时的输出结果为 5 12
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论