4
#include <stdio.h>
typedef struct {
    short x,y;
    char type;
} Tile;

int main(int argc, const char *argv[])
{
    printf("%d\n",sizeof(short));
    printf("%d\n",sizeof(char));
    printf("%d\n",sizeof(Tile));
    return 0;
}

The output is:

2
1
6

I expected sizeof(Tile) to be 5, instead of 6. Is this a well-defined behaviour that structs add one extra byte of memory usage, or is it implementation dependant?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
yasar
  • 13,158
  • 28
  • 95
  • 160

4 Answers4

4

It's because of padding (kind of like rounding).

for example:

struct example1
{
    char a;
    int b;
    char c;
}

struct example2
{
    char a;
    char b;
    int c;
}

will likely differ in size, first will have size of 12B, second will likely only eat 8B (arch and compiler dependant).

Edit: gcc does padding by size of biggest memeber of struct.

Gcc can minimize this behavior by option -fpack-struct, however this may not be best idea ever, it could even backfire (network protocol implementantion is first thing that pops into my mind).

Tomas Pruzina
  • 8,397
  • 6
  • 26
  • 39
  • 1
    Also, if padding causes problems because your reading someone elses data, look into the #pragma pack(n) option. – Java42 Mar 16 '12 at 02:25
  • This is half the answer, however, 6 is not a multiple of 4. – Aatch Mar 16 '12 at 02:55
  • @Aatch Well I am no magician to guess architecture and compiler used (compilers have say in this as well). You can always look into standard (6.2.6.1), it's unspecified behavior. – Tomas Pruzina Mar 16 '12 at 02:59
0

My experimentation shows that the struct is aligned to a 2-byte boundary, as such there is an extra byte of padding at the end.

C padding is implementation specific, and many compilers even allow you to change the alignment settings. There is no specific alignment as set out by the C standard.

However, there are some optimizations on x86_64 for structs that influence this padding decision, for small (<=16 bytes) structs they are passed through registers, and the smallest register is 2 bytes.

As far as I can tell, most C compilers do align on 4 byte boundaries most of the time otherwise, for example this struct:

struct small {
    int x, y;
    char val;
}

is 10 bytes. While this one:

struct big {
    int x, y, z, w;
    char val;
}

is 20 bytes.

In both clang and gcc, structs are aligned to 2 byte boundaries when they are <= 16 bytes and aligned to 4 byte boundaries otherwise.

Aatch
  • 1,846
  • 10
  • 19
  • Strangely, gcc documentation says that gccc align by default by size of biggest array memeber. This struct{char a; long long b; char c; }test; sizeof(test) will thus yield 3*8 = 24B. – Tomas Pruzina Mar 16 '12 at 06:47
  • In your comments you seems to look for some kind of magic behind this, I think it'd be best to sumarize it like. 1) sort stuff by size: struch { char a,b; short c; int d,e,f; long long g } will field optimal: 1+1+2+(3x4)+8=24. – Tomas Pruzina Mar 16 '12 at 06:59
0

You can use the following code to test the structure padding.

#include <stdio.h>

typedef struct {
    char a;
    int b;
    char c;
} Tile;

int main(int argc, const char *argv[])
{
    Tile tile;

    printf("%d %d %d\n", sizeof(int), sizeof(char), sizeof(tile));

    printf("%p\n", &tile.a);
    printf("%p\n", &tile.b);
    printf("%p\n", &tile.c);

    return 0;
}

Each variable must begins at a relative address that can be divided by the size of this variable. For example, if there is a 'short' variable, then it must begins at a relative address 0, 2, 4 ... and so on.

Eric
  • 1
  • 1
  • actually the padding has more to do with general alignment, normally on 4-byte boundaries, but it is implementation specific. Basically the idea is to have each member start on a 4-byte boundary, chars and shorts form a partial exception to this rule, due to memory usage optimizations. – Aatch Mar 16 '12 at 04:05
  • In Visual Studio 2010 I use `#pragma pack(1)` if I do not want to use the padding. – Eric Mar 16 '12 at 07:46
  • After padding, the whole size of this struct must can be divided by the largest variable size in this struct. – Eric Mar 16 '12 at 07:50
0

This is nothing but structure padding.i dont think i should explain as all other answers has enough information.

you can have a look at one of the previous question: here

also there is a nice wiki for data structure allignment which should be very useful to know.

Community
  • 1
  • 1
Vijay
  • 65,327
  • 90
  • 227
  • 319