Why does this structure definition add an extra byte of memory usage?

#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;
}

      

Output:

2
1
6

      

I expected it to sizeof(Tile)

be 5 and not 6. Is this a well-defined behavior that structs add one extra byte of memory usage or is implementation dependent?

+3


source to share


4 answers


This is due to padding (sort of rounding).

eg:

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

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

      



will probably be different in size, at first it will be 12B in size, the second will most likely only consume 8B (depends on arch and compiler).

Edit: gcc does padding for the size of the largest member of the structure.

Gcc can minimize this behavior with the -fpack-struct option, however it might not be the best idea ever, it might even backfire (networking protocol implementation is the first thing that pops into my mind).

+4


source


My experiments show that the structure is aligned with a 2-byte boundary, so there is an extra padding byte at the end.

Addition complements the implementation specifics, and many compilers even let you change alignment settings. There is no special alignment as specified in the C standard.

However, there are several optimizations for x86_64 for structures that affect this padding decision, for small (<= 16 bytes) structures they are passed via registers, and the smallest register is 2 bytes.

As far as I can tell, most C compilers align on 4 byte boundaries in most cases, for example this structure:

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

      



- 10 bytes. Although this one:

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

      

- 20 bytes.

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

0


source


You can use the following code to check if the structure is complete.

#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 start with a relative address, which can be divided by the size of that variable. For example, if there is a "short" variable, it must start at relative addresses 0, 2, 4 ... and so on.

0


source


This is nothing but the padding.i structure, I don't think I should explain as all the other answers contain enough information.

you can take a look at one of the previous questions: here

there is also a good wiki for data structure binding which should be very helpful to understand.

0


source







All Articles