Friday, July 22, 2011

The Mystery about sizeof()

sizeof() is to get the size of a class or an class object. It might be simple conceptually, but there are some details you may not know.

  • what does sizeof() return?
class A
{
  static char x;
  int y;
};

int main()
{
  int s1 = sizeof(A);
}
        s1 = 4. Why s1 = 4? The size of static members will not be counted into the size of the class. The reason is that those static members are stored centrally and shared by all the instances of the class.
  • what does sizeof() return?
class A
{
  char x;
  int y;
};

int main()
{
  A a;
  int s1 = sizeof(A);
  int s2 = sizeof(a);
}
        s1 = 8 and s2 = 8. Why s1 = 8? The size it really needs is just 5 bytes. The reason is for alignment so padding is added. Why s2 = 8? sizeof(a) is equivalent to sizeof(A). Moreover, the padding scheme will sometimes make the order of data members matter. For example, if we have "char a; int x; char b;", the size will be 12. However, if we have "char a; char b; int x;", the size will be 8.
  • what does sizeof() return?
class A
{
  char x;
  int y;
  virtual void bar();
};

int main()
{
  int s1 = sizeof(A);
}
        s1 = 12. Why s1 = 12? Since virtual function is defined, 4 extra bytes need to be allocated for the pointer to virtual function table.

  • what does sizeof() return?
class A
{
  char x;
  int y;
  void bar();
};

int main()
{
  int s1 = sizeof(A);
}
        s1 = 8. Why s1 = 8? Since there is no virtual function defined, we don't need the 4 extra bytes for the pointer to virtual function table. For non-virtual function, there is a central place to find those functions, therefore we don't need such pointer.
  • what does sizeof() return?
class A
{
  char x;
  int y;
  void bar();
};

class B{
   int a;
   A aa;
   virtual void somefunction() ;
}

int main()
{
  int s1 = sizeof(B);
}
        s1 = 16. Why s1 = 16? The size of class A is 8. class B has one integer, one class A instance plus the pointer to the virtual function table. So the total size is 8+4+4 = 16 bytes.
  • what does sizeof() return?
int foo(int n)
{
  char b[n+3];
  return sizeof(b);
}

int main()
{
  int s1 = foo(8);
  
}
        s1 = 11. Why s1 = 11? In this case, at compile time, the compiler can't know the size of array b. The size is known at the run time. That is to say, sizeof() can be evaluated at run time for some case. But for the general case, it is evaluated at compile time.
  • what does sizeof() return?
class ABase{ 
        int iMem; 
}; 

class BBase : public virtual ABase { 
        int iMem; 
}; 

class CBase : public virtual ABase { 
        int iMem; 
}; 

class ABCDerived : public BBase, public CBase { 
        int iMem; 
}; 

int main()
{
   int s1 = sizeof(ABase);
   int s1 = sizeof(BBase);
   int s2 = sizeof(CBase);
   int s4 = sizeof(ABCDerived);
}
        s1 = 4, s2 = 12, s3 = 12 and s4 = 24. Why ? In this case, because BBase and CBase are derived from ABase virtually, they will also have an virtual base pointer (different from the pointer to virtual function table). So, 4 bytes will be added to the size of the class (BBase and CBase). That is sizeof ABase + size of int + sizeof Virtual Base pointer.Size of ABCDerived will be 24 (not 28 = sizeof (BBase + CBase + int member)) because it will maintain only one Virtual Base pointer.
  • what does sizeof() return? (edited on Aug 12)
void foo(int a[])
{
  cout << sizeof(a) << endl;
}

int main()
{  
   int a[10];
   foo(a);
   cout << sizeof(a) << endl;
}
    .    The sizeof() in foo() will return 4 while the one in main() will return 40. The reason is that the a in foo() is actually interpreted as a integer pointer.

2 comments:

  1. int foo(int n)
    {
    char b[n+3];
    return sizeof(b);
    }

    Is this C++? If yes 'char b[n+3];' is illegal.

    ReplyDelete
    Replies
    1. Hi Leve,
      I had tried this piece of code in gcc version 4.2.1 (using g++). At least on my machine, it can be compiled and executed. Maybe this issue is complier specific. If you know a complete answer to this issue, please let me know:)

      Thanks,

      Delete