结构体的大小

1

结构体所占空间的大小,并不是简单地将结构体内所有数据元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何变量的访问都可以从任何地址开始访问,实际上,为了提高存取速度,会进行字节对齐。这就需要各类型数据按照一定的规则在空间上排列,而不是顺序地一个接一个地排放。比如有些平台每次读都是从偶地址开始,一个int型(假设为32位)如果存放在偶地址开始的地方,那么一个读周期就可以读出,而如果存放在奇地址开始的地方,就可能会需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该int数据,显然在读取效率上下降很多。也是用空间换时间。

2

对齐的字节是多大呢?有两个依据,1是系统默认的规则,2是通过指令规定的。系统默认规则时,我们需要理解系统的规则,通过指令则是#pragma pack(n)来设定以n字节对齐方式。

3

规则1

结构体内对齐依据成员的最大字节占用,结构体的大小与成员的顺序有关。
在笔者Mac下(10.11.5 Xcode8.1) 64位环境下,数据类型所占字节

typesizeof
bool1
char1
short2
int4
float4
unsigned int4
long8
long long8
double8
指针8
typedef struct testA
{
    char gender;
    short score;
    int age;
};

age是int型,占用字节最大,故该结构体为4字节对齐,不够4个字节的也会占用4个字节,sizeof(struct testA)的值为8,

typedef struct testB
{
    char gender;
    int age;
    short score;
};

也是4字节对齐,但sizeof(struct testB)的值为结果却为12,为什么呢?
这就是成员顺序的原因了,在结构体testA中布局如下
|gender(1) score(2)|
|age(4)|
4字节对齐时,gender和score总和不超过4,可以放在一起
在结构体testB中布局如下
|gender(1)|
|age(4)|
|score(2)|
gender+age的和超过4,需要重新对齐,score同理。

规则2

结构体内包含子结构体时,在计算子成员的大小时作为字节对齐依据时,子结构体内成员的最大占用字节就是子结构体的占用字节,但子结构体具体的占用空间还是该结构体的实际空间。

typedef struct testC
{
    struct testB other;
    double money;
    short score;
};

testB内最大字节占用是4个字节,而money占用8个字节。所以是8个字节对齐,sizeof(struct testC)大小为32。具体分配如下
other大小占了12位,在4字节对齐的情况下,在testC中依然占12位(4的倍数),在8字节对齐的情况下,就会占用16位(8的倍数)。
testB(16)
money(8)
score(8)
若将money改为int类型,由于testB内最大的占用是age的4个字节,大于money和short的2个字节,故4字节对齐,但testB仍占用12字节, sizeof(struct testC)大小为20位。

总结 字节对齐是一种空间换时间的概念,编译器会对结构体进行处理,结构体的大小与成员类型和顺序有关,并不是简单将其成员大小相加的和。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值