关于内存对齐问题(二)

来源:互联网 发布:松下gt01编程软件 编辑:程序博客网 时间:2024/05/04 23:13
 

一个类的对象到底有多大?其大小由什么因素影响?

我们假定这个类没有继承任何其他类,且没有虚函数。先看下面例子:

         #include <iostream>

using namespace std;

 

class Concrete

{

public:

         Concrete():val(0), c1('A'), c2('B')//, c3('C')

         {

         }

 

private:

         int val;

         char c1;

         char c2;

         //char c3;

};

 

int main(void)

{

         Concrete c;

         cout << sizeof(c) << endl;

 

         return 0;

}

运行上面的程序,不管是否有成员变量c3,输出结果均为8,为什么呢?

由于内存的alignment的原因,所有对象的大小为4bytes的整数倍(因为其数据成员的数据类型最大占用字节数为4,即sizeof(int val) = 4),不足的就填充,如下面的图示。

         关于内存对齐问题(二) - 玄机逸士 - 玄机逸士博客   关于内存对齐问题(二) - 玄机逸士 - 玄机逸士博客                              关于内存对齐问题(二) - 玄机逸士 - 玄机逸士博客

                       (有成员变量c3的情况)                               (没有成员变量c3的情况)

 

出现在derived class中的base class subobject保持其完成原样性

请看下面例子:

#include <iostream>

using namespace std;

 

class Concrete1

{

private:

         int val;

         char c1;

public:

         inline Concrete1(int i, char c1) : val(i), c1(c1)

         {

         }

};

 

class Concrete2 : public Concrete1

{

private:

         char c2;

public:

         inline Concrete2(int i, char c1, char c2) : Concrete1(i, c1), c2(c2)

         {

         }

};

 

class Concrete3 : public Concrete2

{

private:

         char c3;

public:

         inline Concrete3(int i, char c1, char c2, char c3) : Concrete2(i, c1, c2), c3(c3)

         {

         }

};

 

int main(void)

{

         Concrete3 c(1, 'A', 'B', 'C');

         cout << sizeof(c) << endl;

 

         return 0;

}

输出会是多少呢?类Concrete3和1)中的类Concrete完成的功能一模一样,但是Concrete3的对象的空间确变成了16bytes,比原来的整整多出一倍!原因就是C++语言保证“出现在derived class中的base class suboject有其完整性”。图解如下:

关于内存对齐问题(二) - 玄机逸士 - 玄机逸士博客

在上图中Concrete2类型的对象中,为什么也要填充3bytes呢?这还是因为继承了Concrete1的缘故。正是因为继承了Concrete1中的int val,因此Concrete2的对齐数变成了4 bytes,因此必须要填充3 bytes。总结如下:

其一,C++语言保证“出现在derived class中的base class suboject有其完整性”;

其二,derived class的对齐数 = min(指定的全局对齐数,max(base class的对齐数,derived class的对齐数))