6

I have a struct iof_header in my code, and I determined it would be 24 bytes wide. I perform a sizeof(iof_header) and it returns 32 bytes wide.

Question 1 Why is it 32 bytes wide instead of 24?

Question 2 Including its members, how is a struct stored in memory?

Question 3 I find any time I create one of my structs that bytes[4-8 & 20-24] are all NULL, I see this apparent in my char array. The array reads as follows {4 bytes of BASEID_Code, 4 NULL bytes, 8 bytes of zeroed padding, 4 bytes of ASID_Code, 4 NULL bytes, 8 bytes of size} There are NULL bytes at the ends of my unsigned __int32 members, why is this happening?

Is this possibly compile related? Possibly an efficiency thing to make the CPU able to process these data types faster?

struct                      iof_header
{
    union
    {
        struct
        {
            unsigned __int32        BASEID_Code;
            unsigned __int64        padding;
            union
            {
                char                    ASID_Type[4];
                unsigned __int32        ASID_Code;
            };
            unsigned __int64        Size;
        }header;
        char                    header_c[24];
    };
    iof_header()
    {
        header.ASID_Code = 0;
        header.BASEID_Code = 0;
        header.Size = 0;
        header.padding = 0;
    }
};
timrau
  • 22,578
  • 4
  • 51
  • 64
Josh C
  • 1,035
  • 2
  • 14
  • 27
  • 11
    How can a `union` of something and a `char[32]` have a size less than 32 bytes? – Fred Foo Nov 25 '13 at 16:26
  • 1
    Go read this for an exlanation -http://en.wikipedia.org/wiki/Data_structure_alignment – OldProgrammer Nov 25 '13 at 16:27
  • This has been asked and answered a million times already. All three of your questions. Which you should have posted _separately_, if at all. – Lightness Races in Orbit Nov 25 '13 at 16:28
  • 1
    @larsmans Sorry I forgot to change the array back. I already fixed code. I found two solutions to the NULL bytes by trial and error – Josh C Nov 25 '13 at 17:16
  • @LightnessRacesinOrbit I searched, I could not find an answer. I posted. Help stack overflow to improve their search algorithms; beyond that I don't know what to say. Sorry, I suppose? – Josh C Nov 25 '13 at 17:19
  • @Josh Search for `struct sizeof [c++]` and read the top, historic, highly-voted results. – Lightness Races in Orbit Nov 25 '13 at 17:20
  • @LightnessRacesinOrbit Okay, thank you. I would have never thought of the question in that form however – Josh C Nov 25 '13 at 20:51
  • @JoshC: Why not? Those are the two keywords from your question and the language it's about. Sounds like you need some searching practice :P Also, several near-duplicates appear in the Related list, and in a "See these first" list as you wrote your question. – Lightness Races in Orbit Nov 26 '13 at 10:13
  • @LightnessRacesinOrbit The fact of the matter is, I put forth an effort to find an answer to a similar question and could not find one. I can not be faulted for simply being unable to determine a specific method of searching for my question which has been answered. Thank you for the keyword tips, I will try to think of similar search methods in the future. – Josh C Nov 26 '13 at 20:57

2 Answers2

7

Why is it 32 bytes wide instead of 24?

Probably because padding is added before each __int64 member to meet their alignment requirements.

Including its members, how is a struct stored in memory?

The members are stored in order, with padding inserted where necessary to correctly align each member relative to the start of the structure.

Some compilers have a non-standard extension to "pack" the members, so that padding is not inserted. For example, on GCC you can put __attribute__((packed)) after the structure definition.

Possibly an efficiency thing to make the CPU able to process these data types faster?

Yes. On some processors, unaligned accesses are slow; on others, they aren't allowed at all, and must be emulated by two or more accesses.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
2

A compiler is free to add padding bytes after members to preserve alignment requirements. Your __int64 members are probably aligned to 8 bytes, ergo the 4 padding bytes between BASEID_Code and padding.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625