C++ 里sizeof的计算

来源:互联网 发布:python的字典 编辑:程序博客网 时间:2024/06/15 11:53

               那天在网上看了这么一道题目,忽然自己想去搞搞清楚,所以翻资料,整理、测试,得出一个算法来,我把思想记录下来:

得到了以下结论:
    1. 成员的对齐是按声明顺序进行的;
    2. 对齐值由编译指示和最大成员两者较小的值决定;
    3. 未对齐到对齐值的成员一起形成块对齐(联合对齐);
    4. 上一个(下一个)对齐采用自己较大则不变,自己较小则填充自己对齐到上一个(下一个)大小;
    5. 每成员对齐:如果前面已对齐到对齐值,下一个对齐自己。如果前面未对齐到对齐值,如果加上下一个成员不大于对齐值,下一个对齐自己,否则填充自己块对齐到对齐值。
    6. 最后还未对齐到对齐值的,填充空间块对齐到对齐值。
这个可能是套话,大家看下面的计算公式吧,很直观和简单。

我们默认编译器是8字节大小(机器不同可能会有别,我用VS2005做的测试)

class a
{
public:

 double e;//8
 int ttt;//4
 char t;//1
public:
 a();
 ~a();
public:
 virtual double bbo();//8

};

看看上面的函数,这个计算的结果是24

看一下怎么进行的对齐呢?

遵照上面的规则来计算,公式为:8+4+4+8=24,因为int是4个字节,char是1个字节,而4+1=5<8,所以int和char要进行联合对齐了,一共占8个字节,只能每个分到4个字节了!

 

class a
{
public:

  int ttt;//4

  double e;//8
 char t;//1
public:
 a();
 ~a();
public:
 virtual double bbo();//8

};

看下这个呢?我把double房到了int的下面,这样算出来的结果是32,编译器遵从从上到下的方式来进行逐个计算的。

8+8+8+8=32;

 

 

再来看下面的例子

class a
{
public:

 double e;
 int ttt;
 char t;
 int tog;
public:
 a();
 ~a();
public:
 virtual double bbo();

};

8+4+4+8+8 = 32;

 

class a
{
public:

 double e;
 int ttt;
 char t;
 char tog;
public:
 a();
 ~a();
public:
 virtual double bbo();

};

8+4+2+2+8=24;

 

从这几个例子中大家可以很清楚该怎么计算了吧?

 

还有几点需要描述:

1.自然对界(natural alignment)即默认对齐方式,是指按结构体的成员中size最大的成员对齐。

struct naturalalign
{
 char a;
 short b;
 char c;
};

那大小就是2+2+2=6,因为最大的是short为2个字节,对齐就是6了。

2.指定对界

一般地,可以通过下面的方法来改变缺省的对界条件:

  · 使用伪指令#pragma pack (n),编译器将按照n个字节对齐;
  · 使用伪指令#pragma pack (),取消自定义字节对齐方式。

  注意:如果#pragma pack (n)中指定的n大于结构体中最大成员的size,则其不起作用,结构体仍然按照size最大的成员进行对界。

 

原创粉丝点击