有人解释我,类中成员声明的顺序如何决定该类的大小。
例如:
class temp
{
public:
int i;
short s;
char c;
};
上面这个类的大小是8个字节。
但是当成员声明的顺序改变如下
时class temp
{
public:
char c;
int i;
short s;
};
那么类的大小是12个字节。
如何?
答案 0 :(得分:36)
上述行为背后的原因是数据结构对齐和填充。基本上,如果你要创建一个4字节的变量,例如int,它将与四字节边界对齐,即它将从内存中的地址开始,该地址是4 的倍数。同样适用于其他数据类型。 2字节短路应从偶数存储器地址开始,依此类推。
因此,如果你在int之前声明了一个1字节的字符(假设这里是4字节),那么它们之间将剩下3个空闲字节。用于它们的常用术语是“填充”。
Another good pictorial explanation
对齐原因
填充允许更快的存储器访问,即对于cpu,访问对齐的存储区域更快,例如读取4字节对齐的整数可能需要单次读取调用,就好像一个整数位于非对齐的地址范围(比如地址0x0002 - 0x0006),那么它需要两次内存读取获取此整数。
强制编译器避免对齐的一种方法是(特定于gcc / g ++)使用关键字' packed '和structure属性。 packed keyword该链接还指定了如何使用对齐关键字按您选择的特定边界(2,4,8等)强制对齐。
最佳做法
以变量已经与最小填充对齐的方式构造类/结构总是一个好主意。这减少了整体类的大小,加上它减少了编译器完成的工作量,即没有重新排列结构。另外,应始终按代码中的名称访问成员变量,而不是尝试从结构中读取特定字节,假设值将位于该字节处。
另一个有用的SO question on performance advantage of alignment
为了完成,在您的方案(32位机器)中仍然具有8字节的大小,但由于完整的8个字节,它将不会更好现在占用了,并且没有填充。
class temp
{
public:
int i;
short s;
char c;
char c2;
};
答案 1 :(得分:1)
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]]] - &gt ; 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]; i [4-8]; s [8-10]]] - &gt ; 12 填充(1-4)和(10-12)