转自https://www.cnblogs.com/fly1988happy/archive/2012/04/12/2444408.html
恒生春招D卷
1.3 结构体的内存分配(方法二)
struct的内存大小为每个数据内存的加和,首先按照最大的数据类型进行单个分配,如果前一个数据占用不了所有的内存,而剩下的内存可以放下下一个数据,则第二个数据不另外分配内存(但是地址必须是从这个数据类型大小的整数倍开始,看下面的struct C),否则重新分配一个最大类型的内存。(个人觉得这种方法比较好理解!)
例3.
struct A{ struct B{ struct C{
int a; int a; int a;
char b; double b; char b;
double c; char c; short c;
}; }; char d;
}
对于结构体A:
因为A中最大的数据类型是double,占8个字节。所以系统先分配8个字节用来放int,结果int只需要4个就够了,然后剩下的4个字节中的1个可以用来放后面的char,碰到double c时,因为此时的3个字节不能存下,所以再分配了一个8个字节来存放double c。因此A占用16个字节。
对于结构体B:
系统碰到int分给他8个字节存放,碰到double时,剩下的4个字节不足以存放,所以再分配了8个字节,再遇到char时又分配了8个字节,这样B共分配了24个字节。(系统其实是浪费了5个字节的空间)比较A和B,只有变量定义的顺序不一样,结果占用的内存空间也不一样。所以,结构体里面最好按照类型从小到大的顺序来排列,以免浪费空间。
对于结构体C:
按照上述方法,最大的数据类型是int,占4个字节,系统先分配4个字节(03);再分配4个字节(47),存放char b;
short c占2个字节,但是必须从2的整数倍开始,所以应当分配(6~7),
中间空余1个字节;char d占1个字节,但是上次分配的4字节用完了,所以需要再分配4个字节存放char d,d只占用1个字节,所以剩下3个字节空闲。sizeof(struct C)=12。
3.2 联合的内存分配
Union的大小为其内部所有变量的最大值,并且按照类型最大值的整数倍进行内存对齐。
union A union B union C union D
{ { { {
char c[10]; char c[10]; char c[10]; char c;
char cc1; int i; double d; int i;
}u1; }u2; }u3; double d;
}u4;
union A :首先按照char c[10]分配10个字节,然后按照char的1个字节对齐,最终sizeof(u1)=10;
union B :首先按照char c[10]分配10个字节,然后按照int的4个字节对齐,最终sizeof(u2)=12; (大于等于10且能被4整除的最小的数,即12)
union C :首先按照char c[10]分配10个字节,然后按照doube的8个字节对齐,最终sizeof(u3)=16;(大于等于10且能被8整除的最小的数,即16)
union D:按照double分配8个字节,最终sizeof(u4)=8;