13

It is a simple question. Code first.

struct A {
    int x; 
};
struct B {
    bool y;
};
struct C {
    int x;
    bool y;
};

In main function, I call

cout << " bool : " << sizeof(bool) <<
     "\n int : " << sizeof(int) <<
     "\n class A : " << sizeof(A) <<
     "\n class B : " << sizeof(B) <<
     "\n class C : " << sizeof(C) << "\n";

And the result is

bool : 1
int : 4
class A : 4
class B : 1
class C : 8

Why is the size of class C 8 instead of 5? Note that this is compiled with gcc in MINGW 4.7 / Windows 7 / 32 bit machine.

Bleeding Fingers
  • 6,993
  • 7
  • 46
  • 74
Sungmin
  • 2,499
  • 3
  • 26
  • 32
  • @Marlon so, what is the main purpose of the padding? – Sungmin Oct 02 '12 at 01:19
  • @Sungmin: Think about arrays. – Kerrek SB Oct 02 '12 at 01:21
  • 4
    The extra space is *padding*, but the purpose is *alignment*: most architectures are better suited for aligned access to data, so a 32bit `int` aligned to 4 bytes is faster to access (sometimes even atomic) than unaligned memory. In some architectures it is even worse and you cannot use unaligned types directly. – David Rodríguez - dribeas Oct 02 '12 at 01:28
  • Possible duplicate of [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) – Frédéric Hamidi Aug 25 '14 at 08:31

3 Answers3

12

The alignment of an aggregate is that of its strictest member (the member with the largest alignment requirement). In other words the size of the structure is a multiple of the alignment of its strictest (with the largest alignment requirement) member.

struct D
{
  bool a;
  // will be padded with char[7]
  double b; // the largest alignment requirement (8 bytes in my environment)
};

The size of the structure above will be 16 bytes because 16 is a multiple of 8. In your example the strictest type is int aligning to 4 bytes. That's why the structure is padded to have 8 bytes. I'll give you another example:

struct E
{
  int a;
  // padded with char[4]
  double b;
};

The size of the structure above is 16. 16 is multiple of 8 (alignment of double in my environment).

I wrote a blog post about memory alignment for more detailed explanation http://evpo.wordpress.com/2014/01/25/memory-alignment-of-structures-and-classes-in-c-2/

evpo
  • 2,436
  • 16
  • 23
  • 1
    It's not the longest type; it's the alignment of the type whose alignment is "strictest" (i.e. longest). In many ABIs, double's are 8-byte long but only 4-byte aligned, for example. (Theoretically, it should be the LCM of all the alignments, but the standard requires that "Every alignment value shall be a non-negative integral power of two" (3.11, para 4), so you can just take the longest one.) – rici Oct 02 '12 at 04:03
  • what if there is a struct in struct. – M.kazem Akhgary Aug 06 '19 at 04:08
  • @M.kazemAkhgary The alignment requirement of the struct will be considered in the same way as with the plain data types such as double. – evpo Aug 08 '19 at 00:51
2

Aligning structures to the size of a word, which is 4 bytes here.

djechlin
  • 59,258
  • 35
  • 162
  • 290
  • Can I ask further? What is the reason of the aligning structure? – Sungmin Oct 02 '12 at 01:24
  • This doesn't explain the alignment strategy or may be the answer is not complete. If it aligned to 4, then struct B would be 4 bytes too. However, its size is 1 byte. Also in my answer I demonstrated that the compiler aligned to 8 bytes which is not 4 again. My point is that it aligns the size of the structure to a multiple of the largest type it contains. That explains it better. – evpo Oct 02 '12 at 02:15
-1

Looking at the definition of your struct, you have 1 byte value followed by 4 byte Integer. This integer needs to be allocated on 4 byte boundary, which will force compiler to insert a 3 byte padding after your 1 byte bool. Which makes the size of struct to 8 byte. To avoid this you can change order of elements in the struct.

Also for two sizeof calls returning different values, are you sure you do not have a typo here and you are not taking size of pointer or different type or some integer variable.

Answered by Rohit J on struct size is different from typedef version?

Community
  • 1
  • 1
zeroglobal
  • 13
  • 3
  • In my case, changing the order of elements in struct C did not influence the result. – Sungmin Oct 02 '12 at 01:22
  • @Sungmin: The order of the members does not usually affect the padding. Consider that if the `int` must be aligned to a 4 byte boundary, it can be ordered as `bool`, padding, `int`; or `int`, `bool`, padding. Note that in an array, each element is located `sizeof(type)` bytes beyond the previous one. – David Rodríguez - dribeas Oct 02 '12 at 01:29
  • @Sungmin: You're correct. In this case changing the order would not change the size of the `struct`. – David Hammen Oct 02 '12 at 01:30