yasar
yasar

Reputation: 13738

Why does this struct definition add extra one 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;
}

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?

Upvotes: 4

Views: 3166

Answers (4)

Vijay
Vijay

Reputation: 67211

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.

Upvotes: 0

Tomas Pruzina
Tomas Pruzina

Reputation: 8877

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).

Upvotes: 4

Eric
Eric

Reputation: 1

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.

Upvotes: 0

Aatch
Aatch

Reputation: 1856

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.

Upvotes: 0

Related Questions