为什么类的大小取决于成员声明的顺序? 如何?

有人解释我如何在类中的成员声明的顺序决定该类的大小。

例如 :

class temp { public: int i; short s; char c; }; 

上面这个类的大小是8个字节。

但是当成员声明的顺序改变如下

 class temp { public: char c; int i; short s; }; 

那么类的大小是12个字节。

怎么样?

上述行为背后的原因是数据结构对齐和填充 。 基本上,如果要创建一个4字节变量,例如int,它将与四字节边界对齐, 即它将从内存中的地址开始,该地址是4的倍数 。 同样适用于其他数据类型。 2字节短路应从偶数存储器地址开始,依此类推。

因此,如果你在int之前声明了一个1字节的字符(假设这里是4字节),那么它们之间将剩下3个空闲字节。 用于它们的常用术语是“填充”

数据结构对齐

另一个很好的图解说明

对齐的原因

填充允许更快的内存访问,即对于cpu,访问对齐的内存区域更快,例如读取4字节对齐的整数可能需要单个读取调用 ,就好像整数位于非对齐的地址范围(例如地址0x0002 – 0x0006) ,那么需要两次内存读取来获得这个整数。

强制编译器避免对齐的一种方法是(特定于gcc / g ++)使用关键字’ packed ‘和structure属性。 packed关键字此外,该链接还指定了如何使用aligned关键字按您选择的特定边界(2,4,8等)强制对齐。

最佳实践

以变​​量已经与最小填充对齐的方式构造类/结构总是一个好主意。 这减少了整体类的大小,加上它减少了编译器完成的工作量,即没有重新排列结构。 另外,应始终按代码中的名称访问成员变量,而不是尝试从结构中读取特定字节,假设值将位于该字节。

关于对齐性能优势的另一个有用的SO问题

为了完成,在你的场景(32位机器)中,下面仍然会有8个字节的大小 ,但它不会变得更好,因为现在占用了8个字节 ,并且没有填充。

 class temp { public: int i; short s; char c; char c2; }; 
 class temp { public: int i; //size 4 alignment 4 short s; //size 2 alignment 2 char c; //size 1 alignment 1 }; //Size 8 alignment max(4,2,1)=4 

temp [ i [0-4]; s [4-2]; c [6-7]]] – > 8填充(7-8)

 class temp { public: char c; //size 1 alignment 1 int i; //size 4 alignment 4 short s; //size 2 alignment 2 };//Size 12 alignment max(4,2,1)=4 

temp [ c [0-1]; [4-8]; s [8-10]]] – > 12填充(1-4)和(10-12)