您的位置:首页 > 其它

结构体对齐问题

2016-10-27 14:03 225 查看

结构体的成员变量对齐问题:

在嵌入式开发中,多多少少都要遇到这个结构体对齐的问题,特别是某些平台,一不对齐就crash。

还有就是和pc端软件共同协作时,更要统一结构体变量的对齐,否则就牛头不对马嘴了。

今天,就来总结下结构体到底是怎么对齐的。

这个对齐问题可以总结为
两个
问题点:

1. 成员变量的存放起始地址的确定,也就是相对于结构体起始地址的偏移量。

2. 整个结构体变量的大小

在C/C++中,我们可以用
#pragma pack(n)
来定义当前环境的对齐方式(按多少个字节对齐),

我暂且把它叫做
pack
值吧

一、没有指明pack的情况下

当系统没有显示指定pack值时(一般默认按
4字节
对齐),可以认为当前环境的pack值为
max(sizeof(member))


即取所占内存最大的成员变量的字节长度,



struct st{
char a;
short b;
int   c;
}


我们可以认定pack值就是sizeof(int),也就是4字节对齐。

ok,现在确定了环境了的pack值后,接下来确定每个成员变量的起始地址

以上面
st
为例,

对于变量a来说,偏移量就是0,这个没什么疑问

对于b,由于b占两个字节,这时候b的起始地址是从多少开始呢?

先引入一个K,K=min(sizeof(mem),pack),这儿就是说K取当前环境pack值和成员变量内存大小之间的较小值。

这儿,sizeof(b)=2,pack为4,则K=2,即b要从2字节对齐的地址存放,由于a占了一字节,所以要空一个字节出来,接下来才是放变量b

同理,c的存放地址是4字节对齐。

确定好所有成员变量的起始地址后,就能确认整个结构体变量的大小了,即就是当前环境pack值的整数倍。

来几个例子:

struct st{
char a;
short b;
int   c;
}
sizeof(struct st)= 8


struct st{
short a;
short b;
int   c;
}
sizeof(struct st)= 8


struct st{
short a;
char b;
double c;
}
sizeof(struct st)= 16


二、当指定了pack值时

如#pragma pack(N),则要比较下到底该用几字节对齐。新的环境pack值为:pack=min(N,max(sizeof(mem)))

举例说明,#pragma pack(4),还是以上面的st结构体为例,可以得出pack=min(4,4),还是4.

巧合?。。。那我们定义#pragma pack(1) 呢?则pack=min(1,4) pack就为1了,也就是1一字节对齐。

确定pack后,怎么算成员变量的起始地址和结构体大小就和上面一样了。

例子:

#pragma pack(1)
struct st{
short a;
char b;
double c;
}
sizeof(struct st)= 11


说明:

1、当成员变量是数组时,把数组当成多个变量来看,而不要看做一个整体。

如:

struct st{
char a[3];
int  b;
}


把数组当成3个char型的变量就行了。

2、
#define    OFFSET(Type, member)                  (size_t)&( ((Type*)0)->member)


这个宏可以求出成员变量相对于结构体的偏移量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  结构体对齐