为啥类的大小取决于成员声明的顺序?如何?
Posted
技术标签:
【中文标题】为啥类的大小取决于成员声明的顺序?如何?【英文标题】:Why does the size of a class depends on the order of the member declaration? and How?为什么类的大小取决于成员声明的顺序?如何? 【发布时间】:2013-05-03 14:37:54 【问题描述】:有人解释一下类中成员声明的顺序如何决定该类的大小。
例如:
class temp
public:
int i;
short s;
char c;
;
上述类的大小为8字节。
但是当成员声明的顺序改变如下
class temp
public:
char c;
int i;
short s;
;
那么类的大小是12字节。
怎么做?
【问题讨论】:
见data structure alignment 【参考方案1】:上述行为背后的原因是数据结构对齐和填充。基本上,如果您正在创建一个 4 字节变量,例如int,它将与 四字节边界对齐,即它将从内存中的地址开始,该地址是 4 的倍数。同样适用于其他数据类型。 2字节短应从偶数内存地址开始,依此类推。
因此,如果您在 int 之前声明了一个 1 字节的字符(此处假设为 4 字节),则中间将有 3 个空闲字节。用于它们的常用术语是“填充”。
Data structure alignment
Another good pictorial explanation
对齐原因
填充允许更快的内存访问,即对于 cpu,访问对齐的内存区域更快,例如读取一个 4 字节对齐的整数可能需要 单次读取调用,其中好像一个整数位于非对齐地址范围(例如地址 0x0002 - 0x0006),然后需要 两次内存读取 得到这个整数。
强制编译器避免对齐的一种方法是(特定于 gcc/g++)将关键字“packed”与结构属性一起使用。 packed keyword 该链接还指定了如何使用 aligned 关键字按照您选择的特定边界(2、4、8 等)强制对齐。
最佳实践
以变量已经与最小填充对齐的方式构建类/结构总是一个好主意。这减少了整个类的大小,并且减少了编译器完成的工作量,即没有重新排列结构。此外,人们应该始终通过代码中的名称访问成员变量,而不是试图从结构中读取特定字节,假设值位于该字节处。
另一个有用的SO question on performance advantage of alignment
为了完成,在您的场景(32 位机器)中,以下 仍然有 8 个字节的大小,但它不会变得更好,因为 完整的 8 个字节是现在被占用了,并且没有填充。
class temp
public:
int i;
short s;
char c;
char c2;
;
【讨论】:
这是对数据结构对齐的一个很好的解释。谢谢你。 没问题!随时。我对此非常了解,因为曾经在一个关键的嵌入式项目中,我们有一个我们匆忙创建的演示应用程序。由于懒惰并考虑到它的演示,我们通过地址索引初始化了一个数组,即类似 array = "first", "second", "third";最糟糕的部分是它最初运行良好,但在特定目标平台上失败,后来才发现原因是填充。所以这是一个重要的教训。如果其他人能避免同样的错误,我会非常高兴。【参考方案2】: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];i[4-8];s[8-10]]] -> 12 (1-4) 和 (10-12) 中的填充
【讨论】:
以上是关于为啥类的大小取决于成员声明的顺序?如何?的主要内容,如果未能解决你的问题,请参考以下文章