C语言程序设计 | 结构体内存对齐

c语言在计算自定义的结构体的内存时常常要考虑到结构体内存对齐,那么什么是结构体内存对齐呢?

结构体内存对齐规则

1. 第一个成员在与结构体变量偏移量为0的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
        对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值
        VS中默认的值为8
3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
例如下列代码
struct  s1
{
    char  c1;   //默认对齐数:8  vs  变量C1所占字节数:1  ——>对齐数:1
    int   i;    //默认对齐数:8  vs  变量i所占字节数:4  ——>对齐数:4
    char  c2;   //默认对齐数:8  vs  变量c2所占字节数:1 ——>对齐数:1
}

//结构体所占大小为 12个字节
//结构体的最大对齐数:4

在内存中表示为:

因为在结构体s1中,第二个变量i的对齐数是4,所以变量i的存储的地址必须为四的倍数,导致第一个变量c1占完第一个字节后,后面三个字节没有被利用,而是到第四个字节处存储第二个变量i。

当我们调换变量顺序后,结构体占用内存的大小可能会发生变化,例如:

struct  s2
{
    char  c1;     //默认对齐数:8  vs  变量C1所占字节数:1  ——>对齐数:1
    char  c2;     //默认对齐数:8  vs  变量C2所占字节数:1  ——>对齐数:1
    int  i;       //默认对齐数:8  vs  变量i所占字节数:4  ——>对齐数:4
}

//结构体所占大小为 8个字节
//结构体最大对齐数:4

在内存中表示为:

因为第一个变量c1和第二个变量c2的对齐数都是1,所以第一个字节的位置和第二个字节的位置都是1的倍数,因此第一个字节和第二个字节用来存储第一个变量c1和第二个变量c2,而第三个变量i的对齐数是4,所以在第四个字节(4的倍数)的位置存储i。

同理,对于以下代码:

struct  s3
{
    double  d;    //默认对齐数:8  vs  变量d所占字节数:8  ——>对齐数:8
    char  c;      //默认对齐数:8  vs  变量c所占字节数:1  ——>对齐数:1
    int  i;       //默认对齐数:8  vs  变量i所占字节数:4  ——>对齐数:4
}

//结构体大小:16
//结构体最大对齐数:8

而对于嵌套的结构体来说:

struct  s4
{
    char  c1;         //默认对齐数:8  vs  变量c1所占字节数:1  ——>对齐数:1
    struct  S3 s3;    //默认对齐数:8  vs  变量s3所占字节数:8  ——>对齐数:8
    double  d;        //默认对齐数:8  vs  变量d所占字节数:8  ——>对齐数:8
}     

//结构体大小:32
//结构体最大对齐数:8

 

因为变量s3的对齐数是8,所以在第一个字节被变量c1使用后,跳过七个字节,在第八个字节的位置(8的倍数)存储s3。

以上就是关于c语言中结构体内存对齐的知识了,那么为什么结构体要内存对齐了,有以下三个方面的原因:

  1. 不是所有的硬件平台都能访问任意地址上的数据;

  2. 某些硬件平台只能只在某些地址访问某些特定类型的数据,否则抛出硬件异常,及遇到未对齐的边界直接就不进行读取数据了。

  3. 为了代码的可移植性,和提升CPU访问内存的效率,所以结构体一定要内存对齐。

 结构体的内存对齐本质上来说是 以空间换时间 来提高结构体的高效性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值