Life is Good.

Enhance Tech and English
随笔 - 65, 文章 - 20, 评论 - 21, 引用 - 0
数据加载中……

C++sizeof使用规则及陷阱分析

sizeof()返回的是变量声明后所占的内存数,不是实际长度,此外sizeof不是函数,仅仅是一个操作符.

cout<<sizeof(int)<<endl; // 32位机上int长度为4

cout<<sizeof(1==2)<<endl; // == 操作符返回bool类型,相当于 cout<<sizeof(bool)<<endl;

这里有个陷阱,看下面的程序:

   int a = 0;

  cout<<sizeof(a=3)<<endl;

   cout<<a<<endl;

  输出为什么是4,0而不是期望中的4,3???就在于sizeof在编译阶段处理的特性。由于sizeof不能被编译成机器码,所以sizeof作用范围内,也就是()里面的内容也不能被编译,而是被替换成类型。=操作符返回左操作数的类型,所以a=3相当于int,而代码也被替换为:

  int a = 0;

  cout<<4<<endl;

  cout<<a<<endl;

数组问题

  考虑下面问题:

  char a[] = "abcdef";

  char b[] = {'a', 'b', 'c', 'd', 'e', 'f'};

  int c[20] = {3, 4};

   char d[2][3] = {"aa", "bb"};

   cout<<sizeof(a)<<endl; // 7, 表示字符串

        cout<<sizeof(b)<<endl; // 6, 仅表示字符数组

   cout<<sizeof(c)<<endl; // 80

  cout<<sizeof(d)<<endl; // 6

         cout << sizeof(*a) << endl;//1

   cout << sizeof(*b) << endl;//1

   cout << sizeof(*c) << endl;//4

    cout << sizeof(*d) << endl;//3

结论:特别如果字符数组表示字符串的话,数组末自动插入的'\0',在sizeof时不能遗漏,数组a的大小在定义时未指定,编译时给它分配的空间是按照初始化的值确定的,也就是。c是多维数组,占用的空间大小是各维数的乘积,也就是6。可以看出,数组的大小就是他在编译时被分配的空间,也就是各维数的乘积*数组元素的大小。


再分析下面的多维数组问题:

  double* (*a)[3][6];

   cout<<sizeof(a)<<endl; // 4

  cout<<sizeof(*a)<<endl; // 72

   cout<<sizeof(**a)<<endl; // 24

   cout<<sizeof(***a)<<endl; // 4

  cout<<sizeof(****a)<<endl; // 8

  (一)不考虑继承关系(单继承、多继承、虚继承等)

  (1)不带virtual函数时

  空类:

  class A

  { };

  cout << sizeof(A) << endl; // 1

  空类总是返回1

  class B {

  private :

  int value;

  double a;

  public:};

  cout << sizeof(B) << endl; //16

  和struct一样,也要考虑对齐问题,以及成员的顺序因为成员函数不会分配空间,所以sizeof时只计算数据成员的大小

  (2)带virtual函数时

  单继承情况下,只要class中存在virtual函数,编译器在编译时就会自动插入一个指向虚函数表的指针vptr(大小为4字节). 不同的编译器vptr插入的位置可能不同,VC编译器插入vptr的位置一般是数据成员开始。

  下例在MinGW Develper Studio2.05(gcc)下编译,VC 6.0编译器下结果为24  24, 我不太理解为什么...

   class A

   {

   public:

   virtual void foo() {}

   private:

   int m1;

   double m2;

   };

  class B

   {

   public:

  virtual void foo() {}

   private:

   double m2;

   int m1;

   };

  cout << sizeof(A) << endl; // 24

   cout << sizeof(B) << endl; // 24

      产生上面的不同时数据对其的原因。

(3)带static成员时

   class A {

  private :

  int value;

  double a;

  static int CST;

  public:

   };

  cout << sizeof(A) << endl; //16

  因为static成员是分配在全局区为类的所有对象共享(VC编译器可能为了方便将其放入文字常量表), sizeof时不应该计入static成员

posted on 2010-10-26 21:53 Mike Song 阅读(277) 评论(0)  编辑 收藏 引用 所属分类: C/C++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理