内存管理中关于内存对齐的介绍

内存对齐原理

原理

关于C结构体的存储中,存在关于内存对齐的机制,下面以一个结构体为例,说明内存对齐的原理。

struct S1{
    int a;
    unsigned char b;
    long c;
    int d;
    char e;
    char f;
    char* g;
};

struct S1 s1;

s1.a = 0x01;
s1.b = 0x02;
s1.c = 0x1000;
s1.d = 0x10;
s1.e = 0x04;
s1.f = 0x08;
s1.g = NULL;

该结构体在内存中的存储方式如下:
在这里插入图片描述
结构体成员a的地址为0xaee0 ~ 0xaee3,共占4个字节。
成员b的地址为0xaee4,共占1个字节。但紧随其后的3个字节是不可被使用的。
成员c的地址为0xaee8 ~ 0xaeef,共占8个字节。
成员d的地址为0xaf0 ~ 0xaf3,共占4个字节。
成员e的地址为0xaf4,占1个字节。
成员f的地址为0xaf5,占1个字节。但紧随其后的2个字节是不可使用的。
成员g的地址为0xaf8 ~ 0xaff,共占8个字节。


默认情况下的对齐方式是按结构体成员的类型中最长的那个作为基准。如在上述struct S1结构体中,最长的类型就是long和char*,占8个字节。因此其它所有成员都得按8个字节对齐。但它又不是强行将每一个成员都扩充至8个字节长度,而是扩充与压缩多措并举。首先将成员a扩充至8字节,但因int类型仅需4个字节即可,剩余的4个字节不应被浪费,而它后面的成员b所需要的字节数又少于多出的字节数,因此成员b就可以紧随a之后存储数据。如上图所示。在处理好成员a和成员b后仍有3个字节被空闲,但之后的成员c所需的字节数大于剩余的空间,无法合并,故而重新开僻一个8字节空间用于存储成员c。剩下的成员也依此类推。

示例

struct S1{
    int a;
    unsigned char b;
    int d;
    char e;
    char f;
    char x;
    int n;
};
s1.a = 0x01;
s1.b = 0x02;
s1.d = 0x10;
s1.e = 0x04;
s1.f = 0x08;
s1.x = 0x05;
s1.n = 0x0506;

在这里插入图片描述

修改内存对齐的方式

linux默认就是按最长类型作为对齐基准字节数,但我们可以通过关键字"#pragma param(*)"来修改。若我们将对齐字节数修改为1,则结构体在内存中就是普通类型变量的组合,该是多少字节就是多少字节。

#pragma pack() //动态调整,以成员类型最长的字节作为基准数
#pragma pack(1) //以1字节作为对齐基准数。即不对齐。
#pragma pack(4) //以4字节作为对齐基准数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值