结构体中的内存对齐

存在内存对齐的原因
1、平台原因(移植原因):不是所有的硬件都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处取得特定类型的数据,否则抛出硬件异常。
2、性能原因:数据结构(尤其是栈)应该尽可能的在自然边界上对齐,原因是为了访问未对齐的内存,处理器需要作两次内存访问,若内存对齐的话则仅需要访问一次。

举个例子

typedef struct Test
{
        char a;         (char本身占1个字节)因为内存对齐:1+7个字节
        double b;     (double本身占8个字节)内存对齐后还是8个字节
        int c;            (int本身占4个字节内存对齐变成4+4个字节
}Test;
整个Test结构体共占24个字节

内存对齐的依据

  1. 内置类型的对齐值:
  2. 自定义类型的对齐值:
    当我们自定义了一个结构体例如上面的Test结构体,我们就需要按照内部最大的类型进行对齐,上面共有三种类型,字节最大的是double型占8个字节,所以我们找8字节对齐
  3. 程序的指定对齐值
    我们可以利用#pragma pack(4)来对结构体进行指定,制定一个对齐值,结构体内部的元素按照给定的对齐值进行对齐,不够4字节的内存对齐成4字节,超过4字节的保留自己的字节,例如上面的Test结构体就会变成16字节【(1+3)+8+4】
  4. 程序的有效对齐值
    当我们对结构体定义了一个指定的对齐值,但是结构体本身最大类型的对齐值小于指定对齐值,我们将会按照两者之间较小的那个来进行内存对齐,这就是有效对齐值

例如:#pragma pack(8)
typedef struct Test
{
      char a;      1
      int b;         4
      char c;      1
}Test ;
这里程序的指定对齐值是8,而结构体自定义类型的对齐值是4,8大于4,则这个结构体的有效对齐值为4,故这个结构体占12个字节

结构体内部元素顺序对内存大小的影响

typedef struct Test 1
{
      char a;      1
      int b;         4
      char c;      1
}Test 1;
typedef struct Test 2
{
      char a;      1
      char b;      1
      int c;          4
}Test 2;
Test1所占的空间为12个字节【(1+3)+4+(1+3)】
Test2所占空间为8个字节【(1+1+2)+4】

所以为了节约内存空间,我们可以让占用空间较小的成员尽量在一起

在定义结构体的时候也有可能出现嵌套的情况

typedef struct Test
{
      short a;       4
      struct
      {
            int b;      4
            double c;      8
            char d;     1
      };
      int e;     4
}Test;
这个结构体所占空间的大小为40个字节【(4+4)+[(4+4)+8+(1+7)]+(4+4)】

这里是按照8字节对齐的,存在嵌套不是将嵌套的结构体当成一整个类型,还是按照原本的数据类型进行内存对齐

位域、位段

typedef struct Test 1
{
      char a;      1 字节
      char b;      1 字节
      char c;      1 字节
      char d;      1 字节
}Test 1;
typedef struct Test 2
{
      char a : 1;      1 比特位
      char b : 1;      1 比特位
      char c : 1;      1 比特位
      char d : 1;      1 比特位
}Test 2;
Test1占4个字节的空间
Test2占1个字节的空间

  1. 数据不能跨字节存储
    char a:2;
    char b:3;
    这里共占2个字节,但不是一个字节存了a和b的一部分,而是第一个字节的两个比特位存了a,第二个字节的三个比特位存了b
  2. 位域不能跨类型存储
    char a:1;
    int b:1;
    这里一共占了8个字节,存储时不能跨类型,还是要根据之前的类型对齐值进行对齐,只是这里一共实际占用的是8个字节中的2个比特位

当给一个char类型的变量a开辟了2个比特位的空间,a赋值为3(0101),但是这里实际存储的时候a只有2个比特位的空间存3(0101)就会发生截断只存进去了1(01)

内存对齐的本质是用空间换时间,将空间全部变成相同的完整的空间,这样在存取利用时会更加便捷

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值