内存对齐

最近为了找工作,狂补了很多基础知识。自以为掌握的不错了,但是真正笔试、面试的时候才发现不懂的知识真得还很多。对很多知识点的掌握和理解都还停留在表层。

今天总结一下关于字节对齐的知识。

字节对齐在这个找工作季算是被考烂了,笔试考多少次不记得了,面试中被问到的有腾讯、讯飞、先锋商泰等,各家的问的方式不同,但是终究都是考你是否真正掌握了内存对齐。

这一部分从网上抄来的。

一、内存对齐的概述

对于大部分程序员来说,“内存对齐”对他们来说都应该是“透明的”。“内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。

二、内存对齐的原因

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

三、对齐的规则

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
规则:
1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果


字节对齐不仅仅是便于CPU的快速访问,同时也可以有效地节省存储空间。

对于32位机器而言,4字节对齐能够使CPU访问速度提高。比如说一个long类型的变量,如果跨越了4字节边界存储,比如2字节对齐,那么CPU要读两次,这样效率就低了。

所以字节对齐要考虑处理器类型,另外还要考虑编译器类型(vc,GNU gcc默认是4字节对齐)。

在缺省情况下,C编译器为每个变量或是数据单元按其自然对齐条件分配空间。但是可以通过下列方法改变缺省的对其条件:

1、使用伪指令

       #pragma pack(n) //按照n个字节对齐

       ....

       #pragma pack()

       2、

       ._attribute((aligned(n))) // 让所有的结构成员对齐在n字节自然边界上。如果结构中的成员的长度大于n,则按照最大成员的长度来对齐

      ...

      ._attribute_((packed))


四、举例说明

struct AA {

float a; 
char b;
short c;
int *d;
};

1、1字节对齐

#pragma pack(1)

struct AA {

float a; 
char b;
short c;
int *d;
};

#pragma pack()

sizeof(AA) = 11;

内存分布为:

1,1,1,1,1,1,1,1,1,1,1


2、2字节对齐

#pragma pack(2)

struct AA {

float a; 
char b;
short c;
int *d;
};

#pragma pack()


sizeof(AA) = 12;

1,1,

1,1,

1,*,

1,1,

1,1,

1,1


3、4字节对齐

#pragma pack(4)

struct AA {

float a; 
char b;
short c;
int *d;
};

#pragma pack()


sizeof(AA) = 12;

1,1,1,1,

1,*,1,1,

1,1,1,1


4、8字节对齐

#pragma pack(8)

struct AA {

float a; 
char b;
short c;
int *d;
};

#pragma pack()


sizeof(AA) = 12;

5、16字节对齐

#pragma pack(16)

struct AA {

float a; 
char b;
short c;
int *d;
};

#pragma pack()


sizeof(AA) = 12;


8字节和16字节对齐试验证明了"规则"的第3点:"当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果"。







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值