简体   繁体   English

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

[英]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? 我希望sizeof(Tile)为5,而不是6.这是一个定义明确的行为,结构添加一个额外的内存使用字节,还是依赖于实现?

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). 可能会有不同的大小,第一个将有12B的大小,第二个可能只吃8B(拱和编译器依赖)。

Edit: gcc does padding by size of biggest memeber of struct. 编辑:gcc按结构的最大成员的大小填充。

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). Gcc可以通过选项-fpack-struct来最小化这种行为,但这可能不是最好的想法,它甚至可能适得其反(网络协议实现是我脑海中浮现的第一件事)。

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. 我的实验表明结构与2字节边界对齐,因此在结尾处有一个额外的填充字节。

C padding is implementation specific, and many compilers even allow you to change the alignment settings. C填充是特定于实现的,许多编译器甚至允许您更改对齐设置。 There is no specific alignment as set out by the C standard. C标准没有具体的对齐方式。

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. 但是,对于影响此填充决策的结构,x86_64有一些优化,对于它们通过寄存器传递的小(<= 16字节)结构,最小的寄存器是2个字节。

As far as I can tell, most C compilers do align on 4 byte boundaries most of the time otherwise, for example this struct: 据我所知,大多数C编译器大多数情况下都会在4字节边界上对齐,例如这个结构:

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

is 10 bytes. 是10个字节。 While this one: 这一个:

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

is 20 bytes. 是20个字节。

In both clang and gcc, structs are aligned to 2 byte boundaries when they are <= 16 bytes and aligned to 4 byte boundaries otherwise. 在clang和gcc中,结构在<= 16字节时与2字节边界对齐,否则与4字节边界对齐。

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. 例如,如果存在“短”变量,则它必须从相对地址0,2,4 ......开始,依此类推。

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. 还有一个很好的wiki用于数据结构allignment ,这应该是非常有用的知道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM