Incorrect struct size

This is a discussion on Incorrect struct size within the C++ Programming forums, part of the General Programming Boards category; The size of the following struct should be 14 bytes. It appears to be 16 bytes. When I write it ...

  1. #1
    A10
    A10 is offline
    Registered User
    Join Date
    Nov 2006
    Posts
    85

    Question Incorrect struct size

    The size of the following struct should be 14 bytes. It appears to be 16 bytes. When I write it to a binary file, two bytes seem to be inserted after the first two bytes. The two erroneous bytes have the hex values: cc cc. The first four bytes of the struct when filled out appropriately are: 42 4D CC CC

    This is the smallest amount of code that I could reproduce the problem

    Code:
    #include <iostream>
    
    using std::cout;
    using std::cin;
    
    struct bfHeader
    {
    	unsigned short bfType;// = 19778 = 'BM'
    	unsigned int bfSize;// = size of file
    	unsigned short bfReserved1, bfReserved2;// = 0;
    	unsigned int bfOffBits;// = 54;
    };
    
    int main()
    {
    	cout<<"\n Size of ushort: " << sizeof(unsigned short);
    	cout<<"\n Size of uint: " << sizeof (unsigned int);
    	cout<<"\n Expected size of struct: " << sizeof(unsigned short) * 3 + sizeof(unsigned int) * 2;
    	cout<<"\n Size of bfHeader: " << sizeof(bfHeader);
    	cin.get();
    	return 0;
    }
    output
    Code:
     Size of ushort: 2
     Size of uint: 4
     Expected size of struct: 14
     Size of bfHeader: 16
    This was done on VC++ 2008 express. Why is this struct 16 bytes in size?

  2. #2
    A10
    A10 is offline
    Registered User
    Join Date
    Nov 2006
    Posts
    85
    For those that are curious, I discovered a page explaining what the compiler was doing

    The size of my structure is not what I expect it to be

    Compiler specific pragma fixes the problem
    Code:
    #pragma pack(push, 1)
    struct bfHeader
    {
    	unsigned short bfType;// = 19778 = 'BM'
    	unsigned int bfSize;// = size of file
    	unsigned short bfReserved1, bfReserved2;// = 0;
    	unsigned int bfOffBits;// = 54;
    };
    #pragma pack(pop)

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    1,625
    structs are Dword ( 4 byte ) alligned by default
    Devoted my life to programming...

  4. #4
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    Aligning is not a very good idea unless you have a good reason to. Unaligned accesses can slow down your program and pragmas aren't portable.
    Why do you need to? Why can you not just write it out using the >> operator and back using the << operator?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    This is due to padding.

    size of sturcture

  6. #6
    Registered User
    Join Date
    Sep 2009
    Posts
    48
    You should also arrange data types so that they slot together nicely:

    Code:
    struct s1
    {
    	int i;
    	short j;
    	int k;
    	short l;
    };
    
    struct s2
    {
    	int i;
    	int k;
    	short j;
    	short l;
    };
    The size of sizeof(s1) is 16 bytes and the sizeof(s2) is 12 bytes, because the two 2-byte short values can fit into a single 4-byte "slot".

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    It is likely the shorts will be padded, as well. Otherwise they will end up on unaligned addresses.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,677
    Quote Originally Posted by Ushakal View Post
    You should also arrange data types so that they slot together nicely:
    The "slot" theory often doesn't work, as Elysia noted, because shorts are often aligned to a larger byte interval.

    A common rule of thumb is to declare the members in order of decreasing size (i.e. big ones first). That doesn't guarantee no padding but is often a reasonable step towards minimising the total amount of padding added.

    Since alignment of variables on (processor dependent) word boundaries often has a performance benefit most compilers add padding by default. For this reason, the sizes you quoted in your example are not guaranteed.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Sunshine, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. mandelbrot set program improvements
    By mad_muppet in forum Game Programming
    Replies: 3
    Last Post: 07-14-2010, 06:58 AM
  2. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 05:05 AM
  3. Assignment HELP!!
    By cprogrammer22 in forum C Programming
    Replies: 35
    Last Post: 01-24-2009, 02:24 PM
  4. Adventures in labyrinth generation.
    By guesst in forum Game Programming
    Replies: 8
    Last Post: 10-12-2008, 02:30 PM
  5. Replies: 11
    Last Post: 03-25-2003, 05:13 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21