【问题标题】:Zero length struct: what's the pointer pointing at?零长度结构:指针指向什么?
【发布时间】:2020-09-10 19:45:24
【问题描述】:

我一直在玩 C 并遇到了这种情况。

有两个零宽度结构,CD,其中 D 包含 C

如我们所见,指向零长度结构 b 的指针的地址与同样为零长度的结构 a 偏移一个字节(见下面的输出)。

在这种情况下,&a&b 地址指向什么?

为什么它们之间有一个字节的偏移量?

他们不应该都是null指针吗?

#include <stdio.h>

struct C {};

struct D {
    struct C wreck;
};

int main () {

    struct C a;
    struct D b;

    printf("struct C a size %lu stored at %p\n", sizeof(a), &a);
    printf("struct D b size %lu stored at %p\n", sizeof(b), &b);

    return 0;
}

示例输出:

$ ./struc 
struct C a size 0 stored at 0x7ffe05c8b6e6
struct D b size 0 stored at 0x7ffe05c8b6e7

使用的编译器:

$ gcc --version
gcc (Ubuntu 9.3.0-10ubuntu2) 9.3.0

【问题讨论】:

  • 这可能是因为最小的分配单元是一个字节。如果它们是 NULL 指针,它们就不会“存在”。
  • 仅供参考,在严格符合 C 的情况下,结构声明不应为空。struct C {} 是 C++ 或编译器扩展。
  • 一个有趣的实验是定义这些数组并查看其大小。 更新:事实上只是做了它,它是零,从指针算术的角度来看这是有道理的。
  • @EugeneSh.:这很有趣,因为这意味着 &amp;a[0]&amp;a[1] 必须具有相同的地址,这违反了 C 2018 6.5.8 5 中指向具有更大下标的数组元素的规则值比较大于指向具有较低下标值的元素的指针。
  • @EricPostpischil 是的,正是我在答案下评论的内容。在我的实验中,这些确实是相等的。

标签: c struct memory-management


【解决方案1】:

&a 和 &b 地址指向什么?

&amp;aC 类型结构的地址,&amp;bD 类型结构的地址。就好像结构的大小不为零一样。为什么会有所不同?

为什么它们之间有一个字节的偏移量?

因为标准要求两个单独的值不能具有相同的地址。但是&amp;a 位置的单个字节当然不是a 本身的一部分;它是编译器强制插入的填充。

他们不应该都是null指针吗?

没有。为什么应该这样?存在名为 ab 的结构。它们不包含任何数据的事实并不影响它们的存在。 &amp;aa的地址;期望 &amp;a 为 null 就像期望能够在不调用未定义行为的情况下执行 *(NULL) 一样。

【讨论】:

  • 因为标准要求两个单独的值不能具有相同的地址 - 它如何与 struct C a[10];&amp;a[0] 等于 &amp;a[1] 对齐?
  • 关于您的第一个问题,为什么会有所不同?因为如果我们取消引用这个指针,我们会得到一个指向零字节的指针。我认为这不符合 C 标准。我认为 Eric Postpichil 在原帖上的回答是正确的:这是无效的 C。
猜你喜欢
  • 2017-12-07
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
  • 2018-04-03
  • 2016-03-21
  • 2012-03-28
  • 1970-01-01
相关资源
最近更新 更多