sizeof使用规则与陷阱分析

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

C++/C 2010-07-04 22:26:49 阅读23 评论0   字号: 订阅

sizeof不是一个函数,你见过给一个函数传参数,而不加括号的吗?sizeof可以,所以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; // 16

   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成员

  (二)继承关系下

  (1)单继承情况下

  总体上讲, 派生类中需要考虑基类子类型(subtype)的问题,派生对象要考虑基类子对象的问题。

  class A

  {

   public:

  private:

   int m1;

   double m2;

   };

   class B : public A

   {

   public:

   private:

   int m3;

   };

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

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

  同样,要考虑陷阱:基类对齐字节不等于大小

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值