现在的位置: 首页 > 综合 > 正文

结构件对齐(转)

2014年02月19日 ⁄ 综合 ⁄ 共 1356字 ⁄ 字号 评论关闭

#include   <iostream.h>
void main()
{
struct struct1
{
   char p1;
   short p2;
   int p3;
};
struct struct2
{
   char p1;
   int p3;
   short p2;
};

cout<<"the size of the struct1 = "<<sizeof(struct1)<<endl;
cout<<"the size of the struct2 = "<<sizeof(struct2)<<endl;
}

结果是:
the size of the struct1 = 8
the size of the struct2 = 12

仅仅是变量p2和p3换一下位置,结果为什么不一样?
VC++中为结构体分配内存时,先分配一单位长度(结构体中占内存最多数据类型,如
int的长度4),然后在该单位长度中依次为结构中的变量分配空间,直至该单位空间不能再分配完一个完整的变量时为止,就再为该结构体分配另一个单位长度
的存储空间。上例两个结构的实际分配内存为:
struct1 =(1+1空+2)+(4)= 8
struct2 =(1+3空)+(4)+ (2+2空) = 12

-------------------------------------------

分析例子B;
struct B
{
    char b;
    int a;
    short c;
};

设B从地址空间0x0000开始排放。该例子中没有定义指定对齐值,在笔者环境下,该值默认为4。第一个成员变量b的自身对齐值是1,比指定或者默认指定
对齐值4小,所以其有效对齐值为1,所以其存放地址0x0000符合0x0000%1=0.第二个成员变量a,其自身对齐值为4,所以有效对齐值也为4,
所以只能存放在起始地址为0x0004到0x0007这四个连续的字节空间中,复核0x0004%4=0,且紧靠第一个变量。第三个变量c,自身对齐值为
2,所以有效对齐值也是2,可以存放在0x0008到0x0009这两个字节空间中,符合0x0008%2=0。所以从0x0000到0x0009存放的
都是B内容。再看数据结构B的自身对齐值为其变量中最大对齐值(这里是b)所以就是4,所以结构体的有效对齐值也是4。根据结构体圆整的要求,
0x0009到0x0000=10字节,(10+2)%4=0。所以0x0000A到0x000B也为结构体B所占用。故B从0x0000到0x000B
共有12个字节,sizeof(struct B)=12;其实如果就这一个就来说它已将满足字节对齐了,
因为它的起始地址是0,因此肯定是对齐的,之所以在后面补充2个字节,是因为编译器为了实现结构数组的存取效率,试想如果我们定义了一个结构B的数组,那
么第一个结构起始地址是0没有问题,但是第二个结构呢?按照数组的定义,数组中所有元素都是紧挨着的,如果我们不把结构的大小补充为4的整数倍,那么下一
个结构的起始地址将是0x0000A,这显然不能满足结构的地址对齐了,因此我们要把结构补充成有效对齐大小的整数倍.其实诸如:对于char型数据,其
自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,这些已有类型的自身对齐值也是基于数组考虑的,只
是因为这些类型的长度已知了,所以他们的自身对齐值也就已知了.

抱歉!评论已关闭.