结构体-自动对齐和取消自动对齐方法

1.问题点环境
STM32 开发项目使用结构体
2.嵌套结构体

   typedef struct{
   		u32 valid_time1;
   		u32 valid_time2;
   		u32 valid_time3;
	}time_types;

	typedef struct{
		u8 time_zone_id;
		time_types monday_time;
		time_types tuesday_time;
		time_types wednesday_time;
		time_types thursday_time;
		time_types friday_time;
		time_types saturday_time;
		time_types sunday_time;
		time_types holiday_time1;
		time_types holiday_time2;
		time_types holiday_time3;
	}time_zone_group;

	time_zone_group time_zone_group_buf;

定义结构体变量time_zone_group_buf 后使用该变量串口接收上位机数据时,发现单片机分配的内存地址将结构体中time_zone_id 给了4个字节也就是跟后面u32类型同一个字节数,如下图debug时的地址:
time_zone_group 的地址是0x20007CAC,我设定的变量time_zone_id类型是u8类型,也就是一个字节,但monday_time的地址是0x20007CB0,&time_zone_group 和 &monday_time相差有4个字节?后面变量的内存分配字节数都是正常的
在这里插入图片描述

原因分析:
查看资料结构体初始化时,所占的空间将按照占用最大的成员类型所占字节数的整数倍,对于其他成员编译器将自动补齐对应的字节数,也就是说,因为我其他成员变量都是4个字节,而只有time_zone_id 成员是1个字节,编译器在编译的时候自动补全了3个字节。

注: 关于结构体对齐问题,跟单片机系统有关,结合四种对齐规律进行理解:指定对齐值、自身对齐值、有效对齐值、成员偏移量。

在编译时指定该结构体不要自动对齐。
第一种方式:#pragam pack(n) n表示对齐的字节数

#pragam pack(1)
 struct C
 {
    char  a;
    int     b;
    short c;
};#pragam pack()  //还原默认对齐

如不加上#pragam pack() 后面的结构体将都按照1字节当时对齐

第二种方式:attribute((packet))

struct C
{
  char   a;
  int       b;
  short   c;
}__attribute__((packet));

总结:
字节对齐弊端,在跨平台时可能会造成空间消费更大,且有可能导致数据错乱;
可以人为的占位处理

struct C
{
  char   a;
  char  reserve[3];
  int      b;
  short  c;
  char   reserve[2];
}

使用结构体建议:
1.结构体成员合理安排位置,以节省空间;
2.跨平台数据结构可以考虑1字节对齐方式,节省了空间,但影响访问效率;
3.跨平台数据结构人为进行字节填充,提高访问效率但不节省空间;
4.本地数据才用默认对齐方式,以提高访问效率

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值