设为首页 加入收藏

TOP

c/c++之计算数据类型长度问题讲解(sizeof函数)(二)
2018-06-09 10:07:46 】 浏览:465
Tags:c/c 计算 数据 类型 长度 问题 讲解 sizeof 函数

度)的较小者为2,而8是2的倍数,所以刚好满足要求,不用在分配空位置,所以结构体总长度即为8。

(5)类的存储大小计算

类的sizeof值等于类中成员变量所占用的内存字节数。如:

****************************************************************

class A

{

public:

int b;

float c;

char d;

};

int main(void)

{

A object;

cout << "sizeof(object)is " << sizeof(object) << endl;

return 0 ;

}

***************************************************************

输出结果为12(我的机器上sizeof(float)值为4,字节对其前面已经讲过)。

不过需要注意的是,如果类中存在静态成员变量,结果又会是什么样子呢?

***************************************************************

class A

{

public:

static int a;

int b;

float c;

char d;

};

int main()

{

A object;

cout << "sizeof(object) is " << sizeof(object)<< endl;

return 0 ;

}

**************************************************************

16?不对。结果仍然是12.

因为在程序编译期间,就已经为static变量在静态存储区域分配了内存空间,并且这块内存在程序的整个运行期间都存在。

每次声明了类A的一个对象的时候,为该对象在堆上,根据对象的大小分配内存。

如果类A中包含成员函数,那么又会是怎样的情况呢?看下面的例子

*************************************************************

class A

{

public:

static int a;

int b;

float c;

char d;

int add(int x,int y)

{

return x+y;

}

};

int main()

{

A object;

cout << "sizeof(object)is " << sizeof(object) << endl;

b = object.add(3,4);

cout << "sizeof(object)is " << sizeof(object) << endl;

return 0 ;

}

***************************************************************

结果仍为12。

因为只有非静态类成员变量在新生成一个object的时候才需要自己的副本。

所以每个非静态成员变量在生成新object需要内存,而function是不需要的。

注:C++中的多态和虚继承也是非常重要的东西,不过比较复杂,编译器不同,细节也有所不同。

/////////////////////////////////////////////////////////////////////////////////////////////////

如下一段代码:

  #pragma pack(4)

  class TestB

  {

  public:

    int aa;

    char a;

    short b;

    char c;

  };

  int nSize = sizeof(TestB);

  这里nSize结果为12,在预料之中。

  现在去掉第一个成员变量为如下代码:

  #pragma pack(4)

  class TestC

  {

  public:

    char a;

    short b;

    char c;

  };

  int nSize = sizeof(TestC);

  按照正常的填充方式nSize的结果应该是8,为什么结果显示nSize为6呢?

事实上,很多人对#pragma pack的理解是错误的。

#pragma pack规定的对齐长度,实际使用的规则是:

结构,联合,或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。而结构整体的对齐,则按照结构体中最大的数据成员 和 #pragmapack指定值之间,较小的那个进行。

具体解释

#pragma pack(4)

  class TestB

  {

  public:

    int aa; //第一个成员,放在[0,3]偏移的位置,

    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以

这个成员按一字节对齐,放在偏移[4]的位置。

    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以

放在偏移[6,7]的位置。

    char c; //第四个,自身长为1,放在[8]的位置。

  };

这个类实际占据的内存空间是9字节

类之间的对齐,是按照类内部最大的成员的长度,和#pragma pack规定的值之中较小的一个对齐的。

所以这个例子中,类之间对齐的长度是min(sizeof(int),4),也就是4。

9按照4字节圆整的结果是12,所以sizeof(TestB)是12。

如果

#pragma pack(2)

class TestB

  {

  public:

    int aa; //第一个成员,放在[0,3]偏移的位置,

    char a; //第二个成员,自身长为1,#pragma pack(4),取小值,也就是1,所以

这个成员按一字节对齐,放在偏移[4]的位置。

    short b; //第三个成员,自身长2,#pragma pack(4),取2,按2字节对齐,所以

放在偏移[6,7]的位置。

    char c; //第四个,自身长为1,放在[8]的位置。

  };

//可以看出,上面的位置完全没有变化,只是类之间改为按2字节对齐,9按2圆整的结果是10。所以 sizeof(TestB)是10。

最后看原贴:

现在去掉第一个成员变量为如下代码:

  #pragma pack(4)

  class TestC

  {

  public:

    char a;//第一个成员,放在[0]偏移的位置,

    short b;//第二个成员,自身长2,#pragmapack(4),取2,按2字节对齐,所以放在偏移[2,3]的位置。

    char c;//第三个,自身长为1,放在[4]的位置。

  };

//整个类的大小是5字节,按照min(sizeof(short),4)字节对齐,也就是2字节对齐,结果

是6所以sizeof(TestC)是6。


编程开发网
首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++中关于map用法的知识详解 下一篇C++变量命名知识实例讲解