sizeof(struct) weird output in C++

788 views Asked by At

Could somebody please explain the output of this code?

#include <iostream>
using namespace std;

struct Yo{
    char sex;
    int a;
};

int main() {
    Yo c;
    cout<<sizeof(c.sex);
    cout<<endl<<sizeof(c.a);
    cout<<endl<<sizeof(c);
    return 0;
}

Output: 1 4 8

How is the size of structure 8?

2

There are 2 answers

19
AudioBubble On BEST ANSWER

Because of structure padding (aka memory alignment). The alignment has to be a power of two (C11 makes this explicit in 6.2.8p4 as stated by @KeithThompson) and because the total size of your structure is 5, the nearest multiple of 4 is 8 so it gives 8, also because the alignment has to be a power of two.

You can use #pragma pack to have the exact size.

#pragma pack(push, 1) /* set alignment to 1 byte boundary */
struct A {
    char s;
    int a;
};
#pragma pack(pop) // restore to default

Warning: #pragma pack is not in standard C, nor is the assumption that the structure requires 4-byte alignment. As @KeithThompson stated.

"The size of a type must be a multiple of its alignment, but the size needn't be a power of 2. For example, assuming 4-byte int, a structure like struct { int a, b; char d; } will likely have an alignment of 4 and a size of 12. The size is the nearest multiple of the alignment, not the nearest power of 2." - @KeithThompson

Packing is useful to decrease memory, use it when you have a structure full of integers, fixed char lengths, etc. I do not know if it's good to use with pointers but I do not see it useful when using a pointer (e.g. a void * in the struct).

Read more here

2
Chris Dargis On

This is memory alignment.

struct Yo{
    char sex;   // Takes up 1 byte + 3 for padding
    int a;      // Takes up 4 bytes
};

The three bytes between sex and a won't be used because the compiler aligns them for better performance. Thus sex ends up using 1 byte of space and the three bytes after the member variable are used as padding to ensure that int a has an address multiple of 4 (it is 4 byte aligned).