sizeof(struct) doens'nt match inside total size - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

sizeof(struct) doens'nt match inside total size

weeb0weeb0 Posts: 2Member
Hello,

I usually develop in C for embedded platform (mplab C18 from microchip) and I use very often struct.

I began to work on a project on a PC and I encounter one weird behavior which I don't understand :

1st, when I do the sizeof(short, long, int and char) I get :

short : 2
long : 8
int : 4
char : 1

In the following struct, the total size from (sizeof) is 6 but if I do the sum of the size of the differents elements, it should sum 5.

[code]typedef struct _test
{
unsigned char a;
unsigned short b; // 2 bytes
unsigned char c : 4;
unsigned char d : 4;
unsigned char e : 2;
unsigned char f : 6;
}test;[/code]

so:

a = 1 byte
b = 2 bytes
c + d = 1 byte
e + f = 1 byte

Why do the compiler add an empty byte somewhere ? At first, I though it was because the structs must be 2 bytes aligned but the following struct works fine :

[code]
typedef struct _test2
{
unsigned char a;
unsigned char b;
unsigned char c;
}test2;

the sizeof gives me 3 bytes which is right.
[/code]

If I only put 1 short in the structure, the structure is sized 2 bytes. but if I add an unsigned char, the size is not right...

I can't understand whis this behavior and How to bypass this ?

Thank you for your help !

Comments

  • TsagTsag Posts: 5Member
    This is not something that you can bypass. It is something that is platform and implementation defined, meaning that it can change from one system to another and one compiler to another.

    In the case you are seeing with the PC it is a matter of how the hardware has evolved and the means by which the compiler makes the source code meet certain hardware requirements. Alignment, in this case.

    The way structures work isn't as straight forward as most people think and the size of the structure can change depending on the platform it is built for. This is one of the reasons you see some structures that as part of initializing the data members you supply the size of the structure to the structure itself.

    In the case of your structure it becomes 2-byte aligned because of the short (2-byte alignment is required for shorts). If you were to add an int it would become 4-byte aligned.

    The reason for this goes back to hardware, in order for systems to be more efficient, they require certain types of data to be aligned in a certain way.

    char 1-byte aligned
    short 2-byte aligned
    int 4-byte aligned

    a page is 4096-byte aligned

    Here is a code sample that illustrates how things are laid out in a structure. I hope it helps clarify.

    [code]
    #include

    struct Test
    {
    unsigned char a;
    unsigned short b;
    unsigned char c;
    unsigned char d;
    };

    struct Test2
    {
    unsigned int a;
    unsigned short b;
    unsigned char c;
    unsigned char d;
    unsigned char e;
    };



    int
    main(
    void)
    {
    std::cout << "Size of Test (struct): " << sizeof(Test) << std::endl;
    std::cout << " a offset: " << offsetof(Test, a) << std::endl;
    std::cout << " b offset: " << offsetof(Test, b) << std::endl;
    std::cout << " c offset: " << offsetof(Test, c) << std::endl;
    std::cout << " d offset: " << offsetof(Test, d) << std::endl;
    //std::cout << " e offset: " << offsetof(Test, e) << std::endl;
    //std::cout << " f offset: " << offsetof(Test, f) << std::endl;
    std::cout << std::endl;

    std::cout << "Size of Test2 (struct): " << sizeof(Test2) << std::endl;
    std::cout << " a offset: " << offsetof(Test2, a) << std::endl;
    std::cout << " b offset: " << offsetof(Test2, b) << std::endl;
    std::cout << " c offset: " << offsetof(Test2, c) << std::endl;
    std::cout << " d offset: " << offsetof(Test2, d) << std::endl;
    std::cout << " e offset: " << offsetof(Test2, e) << std::endl;

    }
    [/code]

Sign In or Register to comment.