1. 联合体、结构体定义
联合体:在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体。
结构体:结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。
由此看出,“联合”与“结构”有一些相似之处。但两者有本质上的不同。在结构中各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。应该说明的是, 这里所谓的共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。
2.内存分配情况 大家都知道现在我们使用的主流计算机都是32位字长的CPU,对于这个类型的CPU取4个字节的数要比取一个字节高效,也更方便。所以结构体中每个成员的首地址都是4的正数倍的话,取数时就会相对高效更高效。 因此,就有了内存对齐。每个特定平台上的编译器都有自己的默认 对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
规则:
1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。
3.举例说明
- union a {
- int a_int1;
- double a_double;
- int a_int2;
- };
- typedef struct
- {
- a a1;
- char y;
- } b;
- class c
- {
- double c_double;
- b b1;
- a a2;
- };
- cout<<sizeof(a)<<endl;
- cout<<sizeof(b)<<endl;
- cout<<sizeof(c)<<endl;
输出结果为8字节、16字节、32字节, 那么来分析下结构Union中,int为4字节,double为8字节,故联合体sizeof(a)=8。对于结构体b,a占8字节,char占1字节,然后char后面的3个字节补充对齐,构成4整数倍字节。但sizeof(b)为什么不是,8+4=12字节呢。原因在于结构体中存在联合体a,而a呢,占用的是8个字节,对齐系数变成了8。所以char后面的7个字节都是作为对齐补充的。(此处,总结结构体中,对齐系数为4的倍数的最大值为对齐系数。) 结构体c的话就好分析了sizeof(c)=8+16+8=32。