为什么这个结构定义会增加额外的一个字节的内存使用量?

时间:2012-03-16 01:58:17

标签: c memory-management struct

#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.这是一个定义良好的行为,结构添加一个额外的内存使用字节,还是依赖于实现?

4 个答案:

答案 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,知道它应该非常有用。