1
 #include <stdio.h>
 #include <string.h>
 #include <malloc.h>

struct Student {
       char name[100];
       int id;
       char major[50];
       char address[200];
};

int main()
{

     struct Student st;

     strcpy(st.name, "Chuck");
     st.id = 20001;
     strcpy(st.major, "Computer Science");
     strcpy(st.address, "1st Street");

     printf("%d %d %d %d %d\n", sizeof(st), sizeof(st.name),sizeof(st.id), sizeof(st.major), sizeof(st.address));

     return 0;
}

The output is 356 100 4 50 200. Why is sizeof(st) 356, not 354? And I tried this without having int and the output was 350 100 50 200, so I assume the problem is in the integer.

alk
  • 69,737
  • 10
  • 105
  • 255
Woong-Sup Jung
  • 2,337
  • 4
  • 21
  • 20
  • You did not tell which compiler, processor, operating system... are you using – Basile Starynkevitch Mar 29 '13 at 06:38
  • 1
    Don't use `%d` to print `size_t`s. Use `%zu` instead. – autistic Mar 29 '13 at 06:39
  • 1
    @BasileStarynkevitch: It doesn't matter. The answer is the same for all platforms. – Dietrich Epp Mar 29 '13 at 06:39
  • my bad.. I am using visual studio 2010 – Woong-Sup Jung Mar 29 '13 at 06:39
  • @DietrichEpp: It surely does matter in theory. I'm sure that an hypothetical 128 bits word machine with 64 bits `int` will align fields differently than my GCC on Linux x86 in 32 bits mode! There is no guarantee that an `int` is 32 bits (if you want that, `#include ` and use `int32_t`). And some 16 bits machines had 16 bits `int`, e.g. original PCs with Intel 8086 in the 1980s. – Basile Starynkevitch Mar 29 '13 at 06:43
  • 3
    @BasileStarynkevitch: The question is "why does this happen", not "how are fields aligned on my computer". The answer to "why" is the same on all platforms, and you don't need to know how wide `int` is to answer the question. – Dietrich Epp Mar 29 '13 at 06:44
  • 1
    BTW `malloc` is today in `` and the `` header is deprecated (or useful for other non-standard functions that you don't use). – Basile Starynkevitch Mar 29 '13 at 06:59

2 Answers2

7

This is due to padding between struct members. The padding is necessary to ensure that each data member is correctly aligned in memory. The exact alignment requirements depend on your architecture.

Due to this, you cannot assume that the size of a struct equals the sum of the sizes of its members.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
1

Each non-first field in a structure may be preceded by a gap (or padding). The compiler is adding gaps to fit the need of your processor and of the ABI conventions.

You should trust the compiler, it is laying out struct as required by the implementation.

Some compilers provide extensions to alter or improve the structure's layout, e.g. the type attributes of GCC for aligned or packed.

Don't feel the paddings and gaps inside a struct as an issue, but as asset: the compiler tries very hard to satisfy the processor, the ABI conventions, etc...

Most compilers don't reorder fields in structures (GCC used to have a rarely useful optimization which did that, but that optimization has been removed, because sometimes it hurted - e.g. with LTO).

If you care about struct size and if you don't care about the order of the fields, you may reorder them cleverly. But the most dense order could be architecture dependent.

BTW, the C standard does not even guarantee that an int is 32 bits or of a larger size and alignment than char (even if that is very common). It provides <stdint.h> and int32_t for that purpose. I suspect you would not observe any padding or gap if compiling for a 16 bits machine on which int-s are 16 bits (e.g. the original PC AT with Intel 8086 processor from the 1980s, or some cheap 16 bits microcontroller).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • "Each non-first field in a structure may be preceded by a gap (or padding). " -- In this case, none of the fields is preceded by a gap; the gap comes after the last field, to pad the struct size to a multiple of 4. – Jim Balter Mar 29 '13 at 07:32