内存对齐

原创 2015年11月21日 10:15:10

一个常见的例子

struct s1{
    char a;
    char b;
    int c;
}
struct s2{
    char a;
    int c;
    char b;
}

sizeof(s1) = 8;
sizeof(s2) = 12;

内存对齐

内存地址对齐,是一种在计算机内存中排列数据、访问数据的一种方式,包含了两种相互独立又相互关联的部分:基本数据对齐和结构体数据对齐

对于基本数据类型,其地址是内存对齐的:基本类型数据对齐就是数据在内存中的偏移地址必须等于一个字的倍数
而结构体对齐:为了保证访问结构体数据的性能,可能需要在上一个数据结束的地方和当前数据开始的地方插入一些纯粹占位的字符。包括结构体内部元素类型的对齐和结构体本身的对齐

内存对齐的规则为:

1、 对于结构的各个成员,第一个成员位于偏移为0的位置,以后每个数据成员的偏移量必须是min(#pragma pack()指定的数,这个数据成员的自身长度) 的倍数。
2、 在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

看上面中s2的例子,假设编译默认pack(8), a偏移0,c为int,所以其偏移应该是是min(8,4)=4 ,所以需要在a,c之间插入3个填充字节,再看b,其偏移为min(8,1)=1;所以不用考虑。已有的数据占了1+3+4+1=9字节。现在考虑第二条规则,结构体本身也要对齐(这样是为了当声明结构体数组时,能够访问更快),最大的数据成员为int,4字节,min(8,4)=4,所以要加上3字节,9+3=12凑成4的倍数。所以sizeof(s2)=12;
所以上面结构体实际为

struct s2{
    char a;
    char pad[3];
    int c;
    char b;
    char pad[3];
}

那么一个例子
struct{ char a; char b;} 其 size是2bytes. 而不是一定要填充到4字节。因为根据第二条,对齐按char的数据长度来,就是char的倍数即可,所以是 2bytes.

注意数组元素之间是没有填充位的,加了反而会浪费空间,无论声明基本元素还是结构体元素的数组。如果是类型长度小于等于4字节,那么不需要加填充位,因为一次访问一个字就可以把元素取出来,如果大于4字节,那么本来就需要多次访问。
为了优化,重新排列结构体元素顺序或者故意加一些填充位也是可以的。比如OpenCV的图像像素,行首的地址通常需要字节对齐,所以行与行之间的偏移 widthStep不一定等于width*channels, 而是 widthStep = (width*channels + align-1) /align *align;

可以用 #pragma pack来改变编译器默认的内存设置

#pragma pack(push) 
#pragma pack(2)
// your struct define
#pragma pack(pop)

内存对齐的好处

  • 加快数据的访问速度。

计算机内部32位的地址总线,32位的数据总线,所以每次能读取4个字节的数据,而并非一个字节一个字节读取。最低2位A[0],A[1]是不用于寻址,A[2-31]才能存储器相连,因此只能访问4的倍数地址空间
假设一个int 4字节,如果其地址是对齐的(假设是0x3FFFFFF0),那么只需要一次访问内存就能获取4个字节,但是如果其地址是非对齐的(比如0x3FFFFFF1),那么需要连续2次访问内存,分别访问0x3FFFFFF1获得后面3个字节和0x3FFFFFF4获得前面1个字节,并合起来,然后才能获取这个int数据。而由于CPU的处理速度远高于访问内存的速度,所以显然前者要快很多

  • 便于程序移植。而在有些CPU架构上,并不支持非对齐地址的访问,所以如果代码中字节不对齐,对程序移植也会有影响

参考:
内存地址对齐
内存对齐的规则以及作用

相关文章推荐

C/C++内存对齐.pdf

  • 2014年09月23日 00:29
  • 518KB
  • 下载

数据结构内存地址对齐方法

  • 2014年04月07日 16:05
  • 16KB
  • 下载

结构体共用体占用空间区别&&内存对齐

(题目来自牛客网)在32位机器上 设有以下说明和定义:typedef union { long i; int k[5]; char c; } DATE; struct data...

c++内存中字节对齐问题详解

  • 2013年03月02日 19:34
  • 32KB
  • 下载

结构体(struct)的使用、内存分布以及字节对齐测试总结

最近和班上的一些"猿友"重新来完善或重新写以前在学校用C语言实现的数据结构,实现单链表、双向链表、循环链表、树、图等等一些数据结构。需要实现这些数据结构就必须熟练掌握C语言中的自定义类型,即结构体(s...

结构体大小-详解内存对齐问题

  • 2008年11月26日 17:42
  • 3KB
  • 下载

内存对齐问题的完美解释.doc

  • 2008年10月28日 22:07
  • 39KB
  • 下载

在结构体中内存对齐的规则及其重要性

在定义结构体中,一个结构体里面往往有多个变量,而这就牵涉的它们的内存分配问题。下面就说说内存分配的规则和其重要性。 内存分配的规则: ①结构体内第一个成员放在整体的零偏移处。 ②...
  • Tianzez
  • Tianzez
  • 2017年10月09日 21:29
  • 145

C中内存对齐

  • 2012年11月25日 16:52
  • 34KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:内存对齐
举报原因:
原因补充:

(最多只允许输入30个字)