【问题标题】:Why does this struct definition add extra one byte of memory usage?为什么这个结构定义会额外增加一个字节的内存使用量?
【发布时间】:2012-03-16 01:58:17
【问题描述】:
#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。这是一种定义明确的行为,结构会增加一个额外字节的内存使用量,还是依赖于实现?

【问题讨论】:

标签: c memory-management struct


【解决方案1】:

这是因为填充(有点像四舍五入)。

例如:

struct example1
{
    char a;
    int b;
    char c;
}

struct example2
{
    char a;
    char b;
    int c;
}

大小可能不同,第一个大小为 12B,第二个可能只吃 8B(取决于架构和编译器)。

编辑:gcc 按结构最大成员的大小进行填充。

Gcc 可以通过选项 -fpack-struct 最小化这种行为,但这可能不是最好的主意,它甚至可能适得其反(网络协议实现是我想到的第一件事)。

【讨论】:

  • 另外,如果由于您读取别人的数据而导致填充问题,请查看#pragma pack(n) 选项。
  • 这是答案的一半,但是,6 不是 4 的倍数。
  • @Aatch 好吧,我不是猜测使用的架构和编译器的魔术师(编译器也有这个说法)。您可以随时查看标准 (6.2.6.1),这是未指定的行为。
【解决方案2】:

我的实验表明该结构与 2 字节边界对齐,因此末尾有一个额外的填充字节。

C 填充是特定于实现的,许多编译器甚至允许您更改对齐设置。 C 标准没有规定具体的对齐方式。

但是,在 x86_64 上对影响此填充决策的结构进行了一些优化,对于小型(

据我所知,大多数 C 编译器在大多数情况下都会在 4 字节边界上对齐,例如这个结构:

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

是 10 个字节。而这个:

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

是 20 个字节。

在 clang 和 gcc 中,结构为

【讨论】:

  • 奇怪的是,gcc 文档说 gccc 默认按最大数组成员的大小对齐。这个结构{char a;长长 b;字符 c; }测试; sizeof(test) 将因此产生 3*8 = 24B。
  • 在您的 cmets 中,您似乎在寻找某种魔力,我认为最好总结一下。 1) 按大小排序:struch { char a,b;短 c;诠释 d,e,f; long long g } 将是最优的:1+1+2+(3x4)+8=24。
【解决方案3】:

您可以使用以下代码来测试结构填充。

#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 ... 开始,以此类推。

【讨论】:

  • 实际上填充更多地与一般对齐有关,通常在 4 字节边界上,但它是特定于实现的。基本上,这个想法是让每个成员从 4 字节边界开始,由于内存使用优化,字符和短裤构成了该规则的部分例外。
  • 在 Visual Studio 2010 中,如果我不想使用填充,我会使用 #pragma pack(1)
  • 填充后,这个结构的整个大小必须能除以这个结构中最大的变量大小。
【解决方案4】:

这不过是结构填充。我认为我不应该解释,因为所有其他答案都有足够的信息。

您可以查看上一个问题: here

还有一个很好的data structure allignment wiki 应该非常有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 2017-04-13
    • 2013-02-14
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多