#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;
}
输出结果为:
2
1
6
我希望sizeof(Tile)
为5而不是6.这是一个定义良好的行为,结构添加一个额外的内存使用字节,还是依赖于实现?
答案 0 :(得分:4)
这是因为填充(有点像四舍五入)。
例如:
struct example1
{
char a;
int b;
char c;
}
struct example2
{
char a;
char b;
int c;
}
的大小可能会有所不同,第一个将有12B的大小,第二个可能只吃8B(arch和编译器相关)。
编辑:gcc按结构的最大成员的大小填充。
Gcc可以通过选项-fpack-struct来最小化这种行为,但这可能不是最好的想法,它甚至可能适得其反(网络协议实现是我脑海中浮现的第一件事)。
答案 1 :(得分:0)
我的实验表明结构与2字节边界对齐,因此在结尾处有一个额外的填充字节。
C填充是特定于实现的,许多编译器甚至允许您更改对齐设置。 C标准没有具体的对齐方式。
但是,对于影响此填充决策的结构,x86_64有一些优化,对于它们通过寄存器传递的小(&lt; = 16字节)结构,最小的寄存器是2个字节。
据我所知,大多数C编译器大多数情况下会在4字节边界上对齐,例如这个结构:
struct small {
int x, y;
char val;
}
是10个字节。虽然这一个:
struct big {
int x, y, z, w;
char val;
}
是20个字节。
在clang和gcc中,结构在&lt; = 16字节时与2字节边界对齐,否则与4字节边界对齐。
答案 2 :(得分:0)
您可以使用以下代码测试结构填充。
#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;
}
每个变量必须从相对地址开始,该地址可以除以此变量的大小。例如,如果存在“短”变量,则它必须从相对地址0,2,4 ......开始,依此类推。
答案 3 :(得分:0)
这只不过是结构填充。我不认为我应该解释,因为所有其他答案都有足够的信息。
您可以查看上一个问题之一: here
还有一个很好的wiki data structure allignment,知道它应该非常有用。