结构体的大小
发布日期:2021-05-07 16:19:16 浏览次数:15 分类:精选文章

本文共 1480 字,大约阅读时间需要 4 分钟。

1

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

2

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

3

规则1

结构体内对齐依据成员的最大字节占用,结构体的大小与成员的顺序有关。

在笔者Mac下(10.11.5 Xcode8.1) 64位环境下,数据类型所占字节

type sizeof
bool 1
char 1
short 2
int 4
float 4
unsigned int 4
long 8
long long 8
double 8
指针 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位。

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

上一篇:欢迎使用CSDN-markdown编辑器fdsaf
下一篇:Xcode中使用Scheme管理项目

发表评论

最新留言

不错!
[***.144.177.141]2025年04月08日 13时21分13秒