博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

结构体对齐

Posted on 2023-03-13 09:29  乔55  阅读(94)  评论(0编辑  收藏  举报

为什么要对齐

  • 32位架构的cpu,4个字节为一个读周期,设4字节变量在内存首地址为addr
  • addr出现在4的整数倍地址处,方便一个读周期读取
  • 若跨越2个周期拼凑一个4字节,效率低

对齐值

  • 自身对齐值
    • 整数类型自身的对齐值:内置类型自己的尺寸
    • 结构体自身对齐值:数据成员最大的那个自身对齐值
  • 指定对齐值:程序员指定的那个值,不同平台指定的方式:

// vs
#progma pack(8)		// 指定为8字节,32位系统默认为4字节
此时再定义结构体,此结构体的对齐值就是8字节
#pragma pack()		// 取消指定

// linux
typedef struct student{}__attribute__((packed)) student;
  • 有效对齐值:自身对齐值与指定对齐值中较小的那个

结构体对齐要求

  • addr为结构体的对齐起始地址:addr%有效对齐值==0
    • 每个数据成员x都要对齐addr:addr%x有效值==0
    • 结构体自身也要对齐addr:addr%st有交值==0
    • 若无法整除,则addr递增,直接可以整除所有成员及结构体变量本身为止


typedef struct student // C与C++结构体,C++中的类,都可以部分初始化
{	// id:指定4 自身4 有效4	地址:00-03			
	int id;		
        // name:指定4 自身7 有效4	地址:04-11,其中10-11补足1字节	
	char name[7];
        // sa:指定4 自身2 有效2	地址:12-15,其中14-15补足2字节
	short sa;	
	struct
	{
                // month:指定4 自身4 有效4	地址:16-19
		int month;
                // ch1:指定4 自身1 有效1	地址:20-23,其中21-23补足3字节	
		char ch1;	
                // L:指定4 自身8 有效4	地址:24-32
		long long L;
	}date;  //结构体本身 指定4 自身16 有效4			
}student;			// sizeof(student)==32
// 当系统默认的为4,当指定为8时,其结果一样,因为8是读周期4字节的倍数
// 当指定对齐值为2字节时,为28字节,主要少了sa补足的2字节,ch1只需补1字节,省了2字节
// 当指定对齐值为1字节时,为26字节,全不需要补足。