【问题标题】:Why is offsetof(member) equal to sizeof(struct)?为什么 offsetof(member) 等于 sizeof(struct)?
【发布时间】:2013-08-17 15:13:38
【问题描述】:

我有一个结构定义为:

struct smth
{
    char a;
    int b[];
};

当我在这个结构上调用sizeofoffsetof 时:

cout << sizeof(struct smth) << endl;
cout << offsetof(struct smth, b) << endl;

输出是:

4
4

为什么stuct的大小为4,char使用1字节,int数组的偏移量为4? 为什么会有某种填充? 另外,为什么 int 数组根本不占空间?

【问题讨论】:

  • 你的意思是offsetof(struct smth, b),对吧?
  • @CarlNorum 是的,我愿意。已编辑。
  • 是 C 还是 C++?它们是不同的。
  • @YuHao 我专门要求 C++,但添加了 c 标签,以便人们也可以使用该标签找到它。它们有何不同 w.r.t.这个问题的答案?
  • @biox6 您应该只使用相对的标签来标记问题。 C 和 C++ 可能在许多领域是相似的,但它们在更多方面是不同的。在这个问题中,例如,可变长度数组仅在 C 中有效,在 C++ 中无效。

标签: c++ arrays sizeof offsetof


【解决方案1】:

为什么stuct的大小是4,char使用1个字节,int数组的偏移量是4?为什么会有某种填充?

有填充是因为 C 标准允许它;编译器经常对齐变量以提高性能。

另外,为什么第二个变量根本不占用任何空间(似乎是这种情况)?

这是一个 C99 灵活的数组成员 - 这就是它的全部意义所在。我们的想法是分配您的结构,例如:

struct smth *s = malloc(sizeof *s + 10 * sizeof s->b[0]);

然后您将拥有一个结构,其运行方式就像 b 是一个 10 元素数组一样。

【讨论】:

  • 这允许什么样的性能改进?只是好奇。
  • @biox6,一些处理器加载指令只能从字对齐地址加载字。如果您有一个未对齐地址的单词,则需要分别加载每个字节并重新组合。
  • 您的分配语句不考虑对齐约束。通常,它将无法分配正确的内存量。您将改为使用 struct smth *s = malloc(offsetof(struct smth, b[10])); 分配适当大小的结构。
  • @IInspectable,怎么会这样? malloc 需要返回安全对齐的指针,并且结构布局正确。有什么区别?
  • 可能是10 * sizeof s-&gt;b[0]
【解决方案2】:

因为成员 b 的大小为零,并且编译器在 ab 成员之间添加了填充,因此 b 位于“单词”边界上。

但是,如果我没记错的话,像这样的结构中的灵活数组只是有效的 C,而不是 C++,除非作为编译器扩展。

【讨论】:

  • 这是 int b[] 等价于 int *b 吗?
  • 不,不是。 int* b 会使sizeof(smth) 更大,而额外的空间将是一些 int 变量的地址被存储的地方。相反,int b[] 表示该结构应动态分配一些(编译时未知)整数作为单个内存块。
  • @mity 你如何给变量b赋值,你能给我赋值语句吗
  • @Light 查看 Carl Norum 的答案。
  • @Light:给定struct smth *s = malloc(sizeof(*s) + 10*sizeof(*s-&gt;b));,可以写s-&gt;a = 'c'; s-&gt;b[0] = 0; s-&gt;b[9] = 9;
【解决方案3】:

既然 OP 认为问题是 C++:

struct smth
{
    char a;
    int b[];
};

b[] 之类的数组在 C++ 中无效。数组必须具有固定大小。变长数组只在 C99 中有效。

假设你的编译器支持它作为扩展,数组b[] 的大小为零,这使得结构只包含一个char 成员。 struct 中的填充规则有效,将struct 填充为一个单词,即您机器中的 4 个字节。

【讨论】:

    猜你喜欢
    • 2013-02-05
    • 2018-03-21
    • 2022-04-26
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 2013-09-24
    • 1970-01-01
    相关资源
    最近更新 更多