3

why the size of the class cl1 in the following code is 8 but not 5, while the size of class cl2 is 1?

class cl1 {                                                                                                                                                                               
public:                                                                                                                                                                                   
    int n;                                                                                                                                                                                
    char cb;                                                                                                                                                                              
    cl1();                                                                                                                                                                                
    ~cl1();                                                                                                                                                                               
};                                                                                                                                                                                        

class cl2 {                                                                                                                                                                               
public:                                                                                                                                                                                   
    char cb;                                                                                                                                                                              
    cl2();                                                                                                                                                                                
    ~cl2();                                                                                                                                                                               
};                                                                                                                                                                                        
zhanwu
  • 1,508
  • 5
  • 16
  • 27

5 Answers5

6

The compiler is free to insert padding in between and after class members in order to ensure that variables are properly aligned, etc. Exactly what padding is inserted is up to the implementation. In this case, I'd guess that the compiler is adding 3 bytes of padding after cl1::cb, perhaps to ensure that the next variable in memory is aligned on a 4-byte boundary.

Nick Meyer
  • 39,212
  • 14
  • 67
  • 75
  • 2
    Good answer but it's not because you have to align the next variable. The next variable may be a char (align=1) or a long long (e.g., align=8). It's to specifically handle _arrays_ of the type - since the second element's `n` would be align=4, that's why the padding is required. – paxdiablo Feb 22 '11 at 15:11
  • yes, actually I noticed that in my case the compiler always inserts padding to make the size multiple of 4 – zhanwu Feb 22 '11 at 15:17
  • @zhanwu: Design your programs so that they don't rely on the size of a structure. For example, copy members individually also "serialize" each member, not the structure as a whole. – Thomas Matthews Feb 22 '11 at 19:06
3

The largest member of cl1 (n) is 4 bytes, so the size of cl1 is padded up to the nearest 4 bytes (8 in this case) so that an array of cl1 objects does not create n members which are not aligned to 4-byte addresses. Most processors really hate misaligned multi-byte values, either suffering performance losses (two memory cycles to access one value) or outright crashes (alignment exceptions).

There is no guarantee that this will be consistent from compiler to compiler or platform to platform.

Mike DeSimone
  • 41,631
  • 10
  • 72
  • 96
2

This is all due to padding. More info can be found, for example, here

The thing is that the addresses of both the object and its members should be properly aligned for OS and Hardware - specific reasons. Thus the result. The problem of padding is complicated by the fact that objects in an array must be located consecutively, without any space in between, and ALL should be properly aligned.

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
  • Some processors generate *faults* or *exceptions* if they fetch from a location that is not properly aligned. Other processors just make more than one fetch, slowing down program execution time. – Thomas Matthews Feb 22 '11 at 19:09
2

It is because of structure padding by the compiler. If you want to remove the padding, try #pragma pack(1) and you should get 5 and 1 as expected.

Cthutu
  • 8,713
  • 7
  • 33
  • 49
2

While you're exploring the size of struct and how padding is done, let me tell you an interesting thing. The size of struct not only depends on the members, but also on the order of their declaration. For example, size of the following structs is different, even though both has same number of members of same types, the only difference is the order of their declaration!

struct A
{
  int a;
  char b;
  char c;
};

struct B
{
  char b;
  int a;
  char c;
};

cout << "sizeof(A) = " << sizeof(A) << endl;
cout << "sizeof(B) = " << sizeof(B) << endl;

Output:

sizeof(A) = 8
sizeof(B) = 12

Online Demo at Ideone: http://www.ideone.com/8OoxX

Nawaz
  • 353,942
  • 115
  • 666
  • 851