2

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?

5
  • 5
    It's called memory alignment. Commented Jan 13, 2014 at 16:46
  • 2
    and that is what structure padding is! Commented Jan 13, 2014 at 16:48
  • 1
    Because of the padding. You can make the size of the structure exact, you should use #pragma pack() as said here at the end Commented Jan 13, 2014 at 16:50
  • See this question for an example of structure packing. Commented Jan 13, 2014 at 16:52
  • See: en.wikipedia.org/wiki/Data_structure_alignment It's affected by architecture word size. Size likes to match that boundary. Position also likes to match that boundary. (If you'd looked at pointer to instead of sizeof you'd have seen that also) Some of this can be over-ridden. Commented Jan 13, 2014 at 17:10

2 Answers 2

4

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).

Sign up to request clarification or add additional context in comments.

2 Comments

Saying that sex uses 4 bytes of space is wrong. The padding is not part of any member at all.
@GuilhermeBernal: Fair enough point My answer is updated.
1

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

19 Comments

The structure size doesn't have to be a power of 2. Here, it's just padding
The alignment has to, sorry.
The answer still seems wrong to me : put the int before the char in the struct and the sizeof will return 5 : you can't find the sizeof of a struct just by knowing the sum of the sizeof each element
sizeof (struct { int a; char s; } ) == 5 and not 8
What's your point? You still make no sense. 5 is what it's supposed to be after changing memory alignment.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.