内存对齐

Intel奉劝大家,如果想提升性能,那么所有的程序数据都应该尽可能地对齐。(~ ̄▽ ̄)~

为什么要内存对齐

其他少说,先看例子。ヾ(≧▽≦*)o 观察结构体A B ,发现两者的变量顺序不同

#include <bits/stdc++.h>
using namespace std;
struct A
{
    char a;
    int b;
    short c;
};
struct B
{
    char a;
    short b;
    int c;
};
struct C
{
    char a;
    char b;
    short c;
    int d;
};
struct D
{
    char a;
    short b;
    char c;
    int d;
};
int main()
{
    cout<<"sizeof(a):"<<sizeof(A)<<endl;
    cout<<"sizeof(b):"<<sizeof(B)<<endl;
    cout<<"sizeof(c):"<<sizeof(C)<<endl;
    cout<<"sizeof(d):"<<sizeof(D)<<endl;
    return 0;
}

可以看出,输出结果为

sizeof(a):12
sizeof(b):8
sizeof(c):8
sizeof(d):12

可以看出 a,b使用的内存空间并不相同。 下面是他们占用的空间示意图。 a b 问题来了:

为什么不是紧接着排序的?◑﹏◐

这个需要了解地址对齐

为了方便讲述,我们对地址对齐的规则进行一个简单定义(仅为帮助理解,并不严谨)

char   偏移量为sizeof(char)   即 1 的倍数 
short  偏移量为sizeof(short)  即 2 的倍数 
int    偏移量为sizeof(int)    即 4 的倍数 
float  偏移量为sizeof(float)  即 4 的倍数 
double 偏移量为sizeof(double) 即 8 的倍数

在结构体中,从结构体的首地址开始,假设地址从0开始。

a

对结构体A来说

  • a 是 char 类型占 1 个字节,占从 0 ~ 0 的字节
  • b 是 int 类型占 4 个字节,占从 4 ~ 7的字节
  • c 是 short 类型占 2 个字节,从 8 ~ 9 的字节

b

对结构体B来说

  • a 是 char 类型占 1 个字节,占从 0 ~ 0 的字节

  • b 是 short 类型占 2 个字节,从 2 ~ 3 的字节

  • c 是 int 类型占 4 个字节,占从 4 ~ 7的字节

什么是内存对齐

说白了就是调整结构体中数据类型的顺序,使其最终占用空间尽可能小。 看结构体 C 和 D

img 对结构体C来说

  • a 是 char 类型占 1 个字节,占从 0 ~ 0 的字节
  • b 是 char 类型占 1 个字节,占从 1 ~ 1 的字节
  • c 是 short 类型占 2 个字节,从 2 ~ 3 的字节
  • d 是 int 类型占 4 个字节,占从 4 ~ 7的字节

img

对结构体D来说

  • a 是 char 类型占 1 个字节,占从 0 ~ 0 的字节
  • b 是 short 类型占 2 个字节,占从 2 ~ 3 的字节
  • c 是 char 类型占 1 个字节,从 4 ~ 4 的字节
  • d 是 int 类型占 4 个字节,占从 8 ~ 11 的字节

这里就很显著的看出来,结构体排序的顺序对于占用空间的影响还是比较大的。

总结

  • C语言和C++中空类和空结构体的大小 在C++中规定了空结构体和空类的内存所占大小为1字节,因为c++中规定,任何不同的对象不能拥有相同的内存地址。 而在C语言中,空的结构体在内存中所占大小为0。(gcc中测试为0,其他编译器不一定)
  • 不是所有的语言都需要内存对齐,一些语言自动提供内存对齐
  • 为什么要内存对齐?
    • 1.平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
    • 2.性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值