关于字节对齐的看法
2012-07-23 04:04
162 查看
由于CPU的读取内存是以字长为单位的,而内存编址是一字节为单位的,比如一个32位机器,其读取内存一次是4个字节,而并不是一个字节为单位进行读取。因为这个原因,期望编译器变量在编址时要有所调整,以满足最少次数读取原则。
原始类型:
对于长度为一个字节的变量,无论其存放的位置如何都可以一次读取内存来获得其值,比如char a ,放在1,2,3,4,都是通过读取1开始的这个字长块内存,再根据字节地址来获取变量a的值,若放在2上,读取第二个字节开的长度为1的内存块。
同样道理,对于长度为两个字节的变量,那么只要其存放开始地址是偶数,就能通过一次读取内存来获取。对于长度是4的变量,就必须存储在以4的倍数为开始地址的内存块,若不是,则需要CPU进行两次读取,然后再拼凑一次。
但是,对于长度超过4的类型,比如long long类型,其长度为8,我们可以发现,只要起始位置地址数值时4的倍数同样能满足要求。即 存放起始位置 % 类型长度 == 0 || 存放起始位置 % 4 == 0 。
我们发现没,所有原始类型都是2的n次方, 如:1,2,4,8,16......同时编译器对所有变量(包括结构类型变量)编址都是字长(4)的n倍。
结构类型:
结构类型需要看他字节对齐长度和机器字长。
笔者VC默认对齐长度是4,32为机器,这意思是重开始位置开始以4为单位划分块,再加入成员变量,能够容下就放入,不能容下就放入下一个块,对于类型长度超过分块长的,就增加块来放入。在结构的末尾,需要补全,使总长度为4n。
比如,char后跟一个short,那么能够容下,这两个成员将在一个长度为4的块中,要是shrot后再有一个char,同样能够容下,一起放在这个块中。要是short后跟一个int,容不下,所有从下一个块开始放int,要是shourt后更一个double,容不下,放入下一个块,但长度超过4,用两个块来存放。若是长度为6,那么这后面还可以加入两个char哦。
若对齐长度为2,按2来进行填充和补全。
当对齐长度超过机器字长,那么按机器字长来进行进行对齐。比如若设对齐长度为8,那么还是进行着以4为对齐长度的对齐。
通过#pragma pack(n) 和 #pragma pack(pop),来调整对齐长度,一般只需要改为1。当在网络上传输时,不同的机器的默认对齐方式可能不同,接收的buff的解析情况就会有差异。
假设接收一个对象t1的buff,指针p指向buff,若发送接收两方都采用同样的对齐!用p->b来获取不会出错,要是发来这个buff的机器使用的长度为1的对齐,而本机用4,将会出错。
后记:
OK!总算完全理解了!
原始类型:
对于长度为一个字节的变量,无论其存放的位置如何都可以一次读取内存来获得其值,比如char a ,放在1,2,3,4,都是通过读取1开始的这个字长块内存,再根据字节地址来获取变量a的值,若放在2上,读取第二个字节开的长度为1的内存块。
同样道理,对于长度为两个字节的变量,那么只要其存放开始地址是偶数,就能通过一次读取内存来获取。对于长度是4的变量,就必须存储在以4的倍数为开始地址的内存块,若不是,则需要CPU进行两次读取,然后再拼凑一次。
但是,对于长度超过4的类型,比如long long类型,其长度为8,我们可以发现,只要起始位置地址数值时4的倍数同样能满足要求。即 存放起始位置 % 类型长度 == 0 || 存放起始位置 % 4 == 0 。
我们发现没,所有原始类型都是2的n次方, 如:1,2,4,8,16......同时编译器对所有变量(包括结构类型变量)编址都是字长(4)的n倍。
结构类型:
结构类型需要看他字节对齐长度和机器字长。
笔者VC默认对齐长度是4,32为机器,这意思是重开始位置开始以4为单位划分块,再加入成员变量,能够容下就放入,不能容下就放入下一个块,对于类型长度超过分块长的,就增加块来放入。在结构的末尾,需要补全,使总长度为4n。
比如,char后跟一个short,那么能够容下,这两个成员将在一个长度为4的块中,要是shrot后再有一个char,同样能够容下,一起放在这个块中。要是short后跟一个int,容不下,所有从下一个块开始放int,要是shourt后更一个double,容不下,放入下一个块,但长度超过4,用两个块来存放。若是长度为6,那么这后面还可以加入两个char哦。
若对齐长度为2,按2来进行填充和补全。
当对齐长度超过机器字长,那么按机器字长来进行进行对齐。比如若设对齐长度为8,那么还是进行着以4为对齐长度的对齐。
通过#pragma pack(n) 和 #pragma pack(pop),来调整对齐长度,一般只需要改为1。当在网络上传输时,不同的机器的默认对齐方式可能不同,接收的buff的解析情况就会有差异。
struct t { char a; int b; }
假设接收一个对象t1的buff,指针p指向buff,若发送接收两方都采用同样的对齐!用p->b来获取不会出错,要是发来这个buff的机器使用的长度为1的对齐,而本机用4,将会出错。
后记:
OK!总算完全理解了!
相关文章推荐
- 关于字节对齐和运算顺序优先级的讨论
- sizeof(struct)--关于字节对齐的问题
- 关于字节对齐、结构体偏移地址、字位段问题的例子程序说明
- 关于字节对齐问题的解释.
- 关于字节对齐的讨论
- coding---关于字节对齐
- 关于struct和union存储的内存字节对齐的问题
- 关于字节对齐
- 关于字节对齐存储的问题
- 关于字节对齐
- 关于大小端序和字节对齐的总结
- Linux下的 arm-linux-gcc 与 gcc 关于字节对齐问题
- 关于字节对齐的总结
- 关于字节对齐
- [ZZ]关于结构体成员变量的字节对齐的分析
- 关于VC的字节对齐
- 关于字节对齐存储的问题
- 关于字节对齐和继承的关系
- g++中关于字节对齐的测试
- 关于结构体字节对齐的一些感悟