您的位置:首页 > 理论基础 > 数据结构算法

结构体的大小

2016-06-19 21:23 274 查看

1

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

2

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

3

规则1

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

64位下,数据类型所占字节

typesizeof
bool1
char1
short2
int2
float2
unsigned int2
long2
long long2
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;
};


testC内最大字节占用是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类型,sizeof(struct testC)大小为20位。

总结 字节对齐是一种空间换时间的概念,编译器会对结构体进行处理,结构体的大小与成员类型和顺序有关,并不是简单将其成员大小相加的和。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息