码迷,mamicode.com
首页 > 其他好文 > 详细

内存对齐和大小端

时间:2015-04-15 00:38:02      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

一、内存对齐的原因

根本原因:cpu是根据内存访问粒度(memory access granularity,下文简写成MAG)来读取内存,MAG就是cpu一次内存访问操作的数据量,具体数值依赖于特定的平台,一般是2byte、4byte、8byte。

内存对齐:更够减少内存读取次数(相对于内存不对齐),为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

 

二、内存对齐的步骤

 每个平台上的编译器都有自己的默认“对齐系数”。同时,我们也可以通过预编译命令#pragma pack(n)...#pragma pack()来改变对齐系数n,取值为1字节,2字节,4字节,8字节,16字节。

 当结构体进行内存分配时,分两步对齐:

第一、每个结构体成员所分配的存储位置与起始点的偏移量必须能够整除min(对齐系数,成员字节数),这一步可以称为成员对齐;

 

第二、整个结构体所占存储空间要能整除min(max(成员字节数),对齐系数),这一步可以称为结构体对齐。

 

注:由于平常的vc系统默认的pack(8),已经是类型最大的longlong的字节数,所以通常内存对齐都是自然对齐方式。

 

三:大小端的问题和union联合体

  1. 大端模式(Big_endian):字数据的高字节存储在低地址中,而字数据的低字节则存放在高地址中。
  2. 小端模式(Little_endian):字数据的高字节存储在高地址中,而字数据的低字节则存放在低地址中。

 union联合体特点:所有成员的起始地址一致。 

同时:也会根据最新表示的类型覆盖原来的字节的值

  union
{
   int i;
   char a[2];
}*p, u;
p =&u;
p->a[0] = 0x39;
p->a[1] = 0x38;

union 型数据所占的空间等于其最大的成员所占的空间。对union 型的成员的存取都是相对于该联合体基地址的偏移量为0 处开始,也就是联合体的访问不论对哪个变量的存取都是从union 的首地址位置开始。如此一解释,上面的问题是否已经有了答案呢?

int checkSystem( )
{
   union check
   {
      int i;
      char ch;
   } c;
   c.i = 1;
   return (c.ch ==1);
}

内存对齐和大小端

标签:

原文地址:http://www.cnblogs.com/kkshaq/p/4427231.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!