C++ struct size: 2+4+2+2+4 = 16

1.1k views Asked by At

Possible Duplicate:
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?

Why is the sizeof(); of this structure 16 bytes? I'm compiling in g++.

struct bitmapfileheader {       
     unsigned short bfType;
     unsigned int bfSize;
     unsigned short bfReserved1;
     unsigned short bfReserved2;
     unsigned int bfOffBits;   
   };
9

There are 9 answers

0
Andrew Lygin On

I think your compiler uses 4-byte allignment for the fields.

8
Anon. On

The individual fields in a structure need to be aligned appropriately. The compiler will pad additional space in the structure in order to satisfy alignment requirements.

If you don't want this, you can use the UNALIGNED macro.

0
Ramónster On

It's because the 4 byte ints are aligned to a 4 byte boundry, so there are 2 bytes of padding after bfType.

0
Sanjaya R On

Alignment. Likely on your platform ints have to be 4byte aligned and shorts are 2byte aligned.

+0 -1 : bfType
+2 -3 : <padding>
+4 -7: bfSize
+8 -9: bfReserve1
+10 -11: bfReserve2
+12 -15: bfOffBits
-------------
16 bytes

Alignment is good because unaligned structures require extra work for many architectures.

1
Euclid On

because of the way memory is allocated, there will be padding after a short

0
rmn On

This is due to alignment - the compiler has to do some padding.

0
tomkaith13 On

U can pragma pack the structure to avoid padding

0
Pavel Minaev On

ISO C++03, 9.2[class.mem]/12:

Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).

0
coppro On

This issue comes because of a concept known as alignment. In many cases, it is desirable to have a number placed at an address that is a multiple of the size of the number in bytes (up to some maximum, often the pointer size of the platform). A variable so placed is said to be aligned to a n-byte boundary, where n is the number. The exact effects of this depend on the processor. Many processors perform math faster if the data is properly aligned. Some are even incapable of performing operations (sometimes even load operations) on unsuitably-aligned data - in order to work on such data, it has to be loaded into two registers and then a series of bit shifts and masks need to be performed to get a usable value, and then it needs to be put back. Think of it like storing half of the int in each of two buckets and needing to put them together to use it, rather than simply storing the whole int in one bucket.

In your case, the initial bfType likely needs to be aligned to a 2-byte boundary, while bfSize likely needs to be aligned to a 4-byte boundary. The compiler has to accomodate this by aligning the entire struct to 4 bytes, and leaving 2 unused bytes between bfType and bfSize.

When compiling on the same system, however, the padding is probably going to be consistent, possibly depending on compiler options and the specific ABI used (generally, you're safe on the same platform unless you are trying to make things incompatible). You can freely make another struct with the same first 5 members, and they will take up 16 bytes of the other struct, in the exact same positions.

If you really need to avoid this behavior, you will have to check your compiler documentation. Most compilers offer an attribute or keyword to declare a variable as having no alignment, and another one to indicate that a struct should have no padding. But these are rarely necessary in the general course of things.