Reputation: 13738
#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
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
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
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
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