union 和struct大小计算
一、字节对齐
现代计算机的内存空间是按照字节(byte)来划分的,字节对齐的意思是在给特定变量类型分配内存空间的时候,变量的内存地址是它本身变量类型大小的整数倍。比如,给int类型的变量a分配地址空间,因为int类型大小为4字节,所以它的内存地址一定也要是4的整数倍。
即:给变量的地址(起始地址)为它自身类型大小的整数倍。
原因:硬件、cpu存取效率
内存对齐:
在32位系统下,gcc的对齐方式为1,2,4,默认为4字节对齐。
在64为系统下,gcc的对齐方式为1,2,4,8,默认为8字节对齐
在64为系统下,gcc的对齐方式为1,2,4,8,默认为8字节对齐
二、union大小
1)大小足够容纳最宽的成员;
2)大小能被其包含的所有基本数据类型的大小所整除。
(是最大的基本类型的 能容纳最宽成员的整数倍)
union a { char a; int b; char c[10]; };
大小为12 (int -4 , c[10] - 10)
三、struct大小 等于最后一个成员的偏移量加上最后一个成员的大小
偏移量:成员的地址与struct首地址的差,第一个成员偏移量为0
1)结构体变量中成员的偏移量必须是该成员(基本数据类型)大小的整数倍(0被认为是任何数的整数倍) 。 (不是整数倍,在当前成员前填充字节)
2)结构体大小必须是所有成员大小的整数倍。
2)结构体大小必须是所有成员大小的整数倍。
3)如果结构体中的成员又是另外一种结构体,只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的成员的整数倍。
另:为了使内存对齐,结构体大小要是本系统内存对齐数的整数倍,如果不是,在结构体最后一个成员后填充字节,直到结构体占用的内存空间字节数是系统内存对齐数的整数倍后,才是结构体实际占用的内存空间大小。
struct v { double a; short b; char c[3]; short d; char e; };
在32机上占20byte (?) 在64位上24byte。
struct r { double a; short b; short c; char d[3]; char e; };
32 或 64 位上都是 16.
这两个struct中的数据类型一样,只是成员排列顺序不同,占有空间不同。
在定义结构体时,尽量将占用空间最大的数据类型成员定义在前面。