结构体大小计算(pack)
结构体大小计算(pack)
最终大小=成员放置完后的偏移量,向上补齐到min(最大成员自然对齐,pack)的整数倍。1.确定两值:
成员对齐值:控制这个成员自己应该放在哪个偏移位置(比如double不能放在地址不能被8整除的位置)。 整体对齐值:控制整个结构体的大小应该是多少的倍数(方便用数组存放时,每个结构体元素都能自然对齐)。每个成员的对齐值 = min(自身自然对齐, pack):
整体对齐值 = min(最大自然对齐8, pack=4) = 4
例子:
#pragmapack(4)structOne{doubled;//每个成员的对齐值=min(8,4)=4/* 从0开始,然后占八字节,下一个开始的地址为8 */charc;//每个成员的对齐值=min(1,4)=1/* 从8开始,然后占1字节,下一个开始的地址为9 */inti;//每个成员的对齐值=min(4,4)=4/* 9不是成员的对齐值4的整数倍,所以 从12开始,然后占4字节,下一个开始的地址为16 */}//整体对齐值 = min(最大自然对齐8, pack=4) = 4//最终的16是4的整数倍,那么就得到最后的值为16根本判决方法: 确定每个成员对齐值,那么就是确定他们的 起始位置 必须为 成员对齐值的整数倍。 整体对齐值,就是最终当你得出大小的时候,要看是不是整体对齐值的整数倍。2.示例:
2.1 混合类型:
structA{chara;// 1/* PACK(4):每个成员的对齐值=min(1,4)=1 从0开始,偏移1字节,下一个从1开始 */---------------------------------/* PACK(8):每个成员的对齐值=min(1,8)=1 从0开始,偏移1字节,下一个从1开始 */intb;// 4/* PACK(4):每个成员的对齐值=min(4,4)=4 从1开始不是四的整数倍 从4开始,偏移4字节,下一个从8开始 */--------------------------------/* PACK(8):每个成员的对齐值=min(4,8)=4 从1开始不是4的整数倍 从4开始,偏移4字节,下一个从8开始 */shortc;// 2/* PACK(4):每个成员的对齐值=min(2,4)=2 从8开始,偏移2字节,下一个从10开始 */---------------------------------/* PACK(8):每个成员的对齐值=min(2,8)=2 从8开始,偏移2字节,下一个从10开始 */};//整体对齐值 = min(最大自然对齐4, pack=4) = 4//最终的10不是4的整数倍,那么就得到最后的值为12-----------------------------------------//整体对齐值 = min(最大自然对齐4, pack=10) = 4//最终的10不是4的整数倍,那么就得到最后的值为122.2包含double
structB{chara;// 1/* PACK(4):每个成员的对齐值=min(1,4)=1 从0开始,偏移1字节,下一个从1开始 */---------------------------------/* PACK(8):每个成员的对齐值=min(1,8)=1 从0开始,偏移1字节,下一个从1开始 */doubleb;// 8/* PACK(4):每个成员的对齐值=min(8,4)=4 从1开始不是4的整数倍 从4开始,偏移8字节,下一个从12开始 */---------------------------------/* PACK(8):每个成员的对齐值=min(8,8)=8 从1开始不是8的整数倍 从8开始,偏移8字节,下一个从16开始 */intc;// 4/* PACK(4):每个成员的对齐值=min(4,4)=4 从12开始,偏移4字节,下一个从16开始 */---------------------------------/* PACK(8):每个成员的对齐值=min(4,8)=4 从16开始,偏移4字节,下一个从20开始 */};//整体对齐值 = min(最大自然对齐8, pack=4) = 4//最终的16是4的整数倍,那么就得到最后的值为16-----------------------------------------//整体对齐值 = min(最大自然对齐8, pack=8) = 8//最终的20不是8的整数倍,那么就得到最后的值为242.3.结构体成员的自然对齐都小于 pack
structC{chara;// 1shortb;// 2charc;// 1};pack(4)----->6pack(8)----->62.4数组和嵌套结构体
structD{chararr[3];// 3个char,自然对齐1intx;// 4shorty;// 2};pack(4)----->12pack(8)----->12最后两个用来自我检测