Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sizeof(), alignment in C structs:

Preface: Did my research about struct alignment. Looked at this question, this one and also this one - but still did not find my answer.

My Actual Question:

Here is a code snippet I created in order to clarify my question:

#include "stdafx.h"
#include <stdio.h>

struct IntAndCharStruct
{
    int a;
    char b;
};

struct IntAndDoubleStruct
{
    int a;
    double d;
};

struct IntFloatAndDoubleStruct
{
    int a;
    float c;
    double d;
};

int main()
{
    printf("Int: %d\n", sizeof(int));
    printf("Float: %d\n", sizeof(float));
    printf("Char: %d\n", sizeof(char));
    printf("Double: %d\n", sizeof(double));
    printf("IntAndCharStruct: %d\n", sizeof(IntAndCharStruct));
    printf("IntAndDoubleStruct: %d\n", sizeof(IntAndDoubleStruct));
    printf("IntFloatAndDoubleStruct: %d\n", sizeof(IntFloatAndDoubleStruct));
    getchar();
}

And it's output is:

Int: 4
Float: 4
Char: 1
Double: 8
IntAndCharStruct: 8
IntAndDoubleStruct: 16
IntFloatAndDoubleStruct: 16

I get the alignment seen in the IntAndCharStruct and in the IntAndDoubleStruct.

But I just don't get the IntFloatAndDoubleStruct one.

Simply put: Why isn't sizeof(IntFloatAndDoubleStruct) = 24?

Thanks in advance!

p.s: I'm using Visual-Studio 2017, standard console application.

Edit: Per comments, tested IntDoubleAndFloatStruct (different order of elements) and got 24 in the sizeof() - And I will be happy if answers will note and explain this case too.

like image 623
MordechayS Avatar asked Jun 12 '18 10:06

MordechayS


People also ask

Can you use sizeof on a struct in C?

Even though the c field doesn't need padding, the struct will generally have a sizeof(struct foo_t) == 8 (on a 32-bit system - rather a system with a 32-bit int type) because there will need to be 3 bytes of padding after the c field.

Can you use sizeof on a struct?

The sizeof for a struct is not always equal to the sum of sizeof of each individual member. This is because of the padding added by the compiler to avoid alignment issues. Padding is only added when a structure member is followed by a member with a larger size or at the end of the structure.

What is meant by sizeof () of a structure?

In C language, sizeof() operator is used to calculate the size of structure, variables, pointers or data types, data types could be pre-defined or user-defined. Using the sizeof() operator we can calculate the size of the structure straightforward to pass it as a parameter.


1 Answers

On your platform, the following holds: The size of int and float are both 4. The size & alignment requirement of double is 8.

We know this from the sizeof output you've shown. sizeof (T) gives the number of bytes between the addresses of two consecutive elements of type T in an array. So we know that the alignment requirements are as I've said above. (Note)

Now, the compiler reported 16 for IntFloatAndDoubleStruct. Does it work out?

Assume we have such an object at an address aligned to 16.

  • int a is therefore at address X aligned to 16, so it's aligned to 4 just fine. It will occupy bytes [X, X+4)
  • This means float c could start at X+4, which is aligned to 4, which is fine for float. It will occupy bytes [X+4, X+8)
  • Finally, double d could start at X+8, which is aligned to 8, which is fine for double. It will occupy bytes [X+8, X+16)
  • This leaves X+16 free for the next struct object, again aligned to 16.

So there's no reason to start any of the members later, so the whole struct fits into 16 bytes just fine.


(Note) This is not strictly true: for each of these, we know that both size and alignment are <= N, that N is a multiple of the alignment requirement, and that there is no N1 < N for which this would also hold. However, this is a very fine detail, and for clarity the answer simply assumes the actual size and alignment requirements for the primitive types are indetical, which is the most likely case on the OP's platform anyway.

like image 181
Angew is no longer proud of SO Avatar answered Sep 30 '22 21:09

Angew is no longer proud of SO