Reputation: 689
I am writing a program to unpack PE files. I have a struct, Pe_SymbolHeader. It looks like this:
typedef struct _Pe_SymbolHeader {
char Name[8]; // 8
uint32_t Value; // 12
uint16_t SectionNumber; // 14
uint16_t Type; // 16
uint8_t StorageClass; // 17
uint8_t NumberOfAuxSymbols; // 18
} Pe_SymbolHeader;
gcc is telling me the size of this struct is 20 bytes.
printf("sizeof Pe_SymbolHeader %d\n", sizeof(Pe_SymbolHeader));
I decided to place a Pe_SymbolHeader on the stack and take a look at where everything was located in memory
Pe_SymbolHeader test
printf("%p\n", &(test.Name));
printf("%p\n", &(test.Value));
printf("%p\n", &(test.SectionNumber));
printf("%p\n", &(test.Type));
printf("%p\n", &(test.StorageClass));
printf("%p\n", &(test.NumberOfAuxSymbols));
This gave me the following, which seems ok:
0x7fffffffe150
0x7fffffffe158
0x7fffffffe15c
0x7fffffffe15e
0x7fffffffe160
0x7fffffffe161
So if gcc is using 18 bytes to store my struct, why is sizeof telling me the struct will take 20 bytes?
Edit: Ok, it seems what gcc is doing to try and help me is what is killing me, and several answers are correct. I can only vote for one, but thank you those who answered.
Upvotes: 1
Views: 1256
Reputation: 4967
uint32_t Value;
this is adding 6 bytes as opposed to expected 4. I tend to agree with Jonathan Leffler about the underlying reasons.
Upvotes: 1
Reputation: 146211
There is padding at the end of the struct.
The reason has to do with what happens in an array or possibly some other context where something follows your struct. That something might be another instance of this struct. The struct contains a 32-bit object so it will have an alignment requirement of 32 bits.
The compiler very much wants the next item to start on a natural word boundary for the architecture it is compiling for, so that any field in the next object can be read with a single operation instead of two operations plus some fiddling to combine two different "words".
Upvotes: 3
Reputation: 754820
The uint32_t
part of the structure needs to be aligned on a multiple of 4 bytes, so the size of the structure has to be a multiple of 4 bytes to ensure that an array of the structure will not cause trouble (misaligned access trouble - which can lead to SIGBUS errors on some machines and to (very) inefficient access on (most) other machines). Therefore, the compiler mandates 2 padding bytes at the end of the structure; these have no name, so you cannot legitimately access them.
Upvotes: 3
Reputation: 1494
So if gcc is using 18 bytes to store my struct, why is sizeof telling me the struct will take 20 bytes?
Put 2 structs like this on the stack and print the same thing for both of them, this will enlighten you.
Upvotes: 2