结构体大小如何计算?

以下内容摘自此处:
作者:太平小小草
链接:https://www.jianshu.com/p/e772fff47465
来源:简书

结构体大小计算有三个原则:
一,结构体变量的首地址,必须是结构体 "最宽基本类型成员" 大小的整数倍(0被认为是任何数的整数倍)。
二,结构体每个成员相对于结构体首地址的偏移量,都是该成员的整数倍
三,结构体的总大小,为结构体 “最宽基本类型成员” (将嵌套结构体里的基本类型也算上,得出的最宽基本类型) 大小的整数倍

个人理解其中最宽基本类型成员:指的就是占字节数最大的类型成员。下面给出一个表格,方便查看各个类型的字节数:在这里插入图片描述

下面给出一些计算结构体大小的例子:

1.简单结构体

1.1
struct s1{
char ch1;
char ch2;
int i;
};

这个结构体的大小容易计算,为8。ch1和ch2共同占4字节,i占4字节,共8字节。

1.2
struct s1{
char ch1;
int i;
char ch2;
};

这个和上面哪个只是结构体成员顺序换了一下,但大小就变成了12。是因为要满足偏移量是成员的整数倍,ch1偏移量是0,i的偏移量不可能是1,因为1不是i(大小4)的倍数,所以i的偏移量是4,ch2的偏移量就变为了8,加ch2是9,要满足结构体大小是成员大小整数倍,就是12。

2.成员包含数组的结构体

2.1
struct s2{
char ch;
int i;
char str[10];
};

这个结构体的大小是20,先看前两个成员,大小是8,毋庸置疑,这个char类型的数组,只需要把它看做十个char连在一起即可,加起来就是18,再满足结构体大小为成员整数倍,所以大小就是20。
含数组成员A array[n],就把这个数组看成n个A类型的数据连在一起即可。

3.嵌套结构体的结构体

3.1
struct s3{
    char ch;
    int i;
    struct s{
        char ch1;
        int j;
    }sub;
    float f;
};

里面这个结构体的大小是8,那么是否结构体大小就要向8对齐呢?这个结构体的大小是20,很明显不是8的倍数。所以计算结构体大小时是把里面这个结构体就看做是一个char,和一个int,不是看做一个整体。
最宽基本类型成员是j (4位),则
ch占4个字节,i占4个,ch1占4个,j占4个,f占4个,一共20。

3.2
struct s3{
    char ch;
    char i;
    struct s{
        char ch1;
        int j;
    }sub;
    char f;
};

注意这里结构体(s3)里的结构体(s)内的数据并不能与之前的数据进行内存对齐。
s里面的ch1与上面的ch,i不能共同占用4个字节,得另外开辟4个字节内存。这点需要注意一下。故大小为4+4+4+4=16而不是4+4+4=12。

3.3
struct s3{
    char ch;
    char i;
    struct s{
        char ch1;
        double j;
    }sub;
    char f;
};

最宽基本类型成员是j (8位),则
ch和i共占8个字节,ch1占8个,j占8个,f占8个,一共32。

4.成员包含联合体的结构体

4.1
struct s5{
char ch;
int i;
union{
char ch1;
int j;
};
};

联合体大小就是成员中最大类型的大小,所以这个结构体大小是12.
4(ch)+4(i)+4(j)=12。

5.指定对齐值

指定对齐值:#pragma pack(n) //指定向n对齐
#pragma pack(n) 若以 #pragma pack()作结束,表示该种对齐方式至此为止。

5.1对齐值小于最大类型成员值
#pragma pack(4)  //指定向4对齐 最大是8
struct s6{
char ch;
int i;
float f;
double d;
};

如果我们没有指定对齐值,这个结构体大小是8(ch、i)+8(f)+8(d)=24,我们指定向4对齐,所以大小是4的倍数,所以结构体大小是4(ch)+4(i)+4(f)+4(d)+4(d)=20。

5.2对齐值大于最大类型成员值
#pragma pack(10) //指定向10对齐 最大是8
struct s7{
char ch;
int i;
float f;
double d;
};

我们指定的对齐值是10,最大为8,是否就向10对齐?不是,当指定对齐值大于自身对齐值时,向自身对齐值对齐,大小是24,即8(ch、i)+8(f)+8(d)=24。

总的来说,应向指定对齐值和自身对齐值中较小的那个值对齐。

  • 30
    点赞
  • 142
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值