【问题标题】:Cannot assign union member as NULL无法将联合成员分配为 NULL
【发布时间】:2015-11-20 15:08:40
【问题描述】:

我有一个联合定义如下:

union simple_list
{
    simple_list *next;
    int *s;
};

这是我的主要功能:

int main()
{
    simple_list *sl;
    sl->next = NULL; // core dumped, why?

    simple_list sl1;
    sl1.next = NULL; // this will be fine

    simple_list *sl2;
    sl->next = sl2; // this also will be fine

    return 0;
}

我不能通过指针访问工会成员之一吗?

补充: 现在,答案很明确了。因为我试图在为其分配内存之前访问一个指针,而这种操作是未定义的。 我这样修改了我的代码,然后一切正常。

simple_list *sl = (simple_list*)malloc(sizeof(union simple_list));

但是,我发现另一个问题:

int main()
{
    simple_list *sl = (simple_list*)malloc(sizeof(union simple_list));
    sl->next = NULL;  // this should be fine and it does

    simple_list *sl1;
    sl1->next = NULL; // amazing! this also be fine, "fine" means no core dumped

    return 0;
}

这是否意味着未定义的操作可能(不是必须)导致核心转储错误?

我用 gcc 4.8.4 编译我的 C 代码。 Ubuntu 14.04 虚拟机。

更新:2015-12-16

核心转储意味着分段错误。我最近读了一些关于操作系统的书,分段错误意味着您尝试访问一些尚未为您分配的内存。当我声明一个指针但不为其分配内存时,指针悬空。悬空意味着这个指针可以指向任何地方,因此成功或不成功地引用该点是合理的。到目前为止一切顺利!

【问题讨论】:

    标签: c pointers unions


    【解决方案1】:

    您必须在分配之前为sl 分配内存。否则,sl->next = NULL; 将调用未定义的行为。

    【讨论】:

    • 这个答案对 OP 有帮助吗?
    • 除了我指出的所有 UB 以及它有点不精确的事实,我敢说它确实有帮助。我是赞成票之一。我一直喜欢简短的回答。
    • @Kay;为什么不??你觉得我应该写如何分配内存?
    • 你的答案现在更好了。也许您可以添加一个词,为什么在分配任何值之前不应取消引用指针。 IE。缺少默认值。
    • @Kay;有很多东西可以添加到答案中,添加这些东西并不会改善它,就像你说的:“在分配任何值之前你不应该取消引用指针”:是的,但不适用于此答案。这里没有指针解引用。只有初始化。答案很准确。
    【解决方案2】:

    union 是 C 中的一个棘手的野兽。未定义的行为永远不会太远。详细:

    1. simple_list *sl; sl->next = NULL; 行为是未定义。您尚未将指针 sl 分配给任何内存。

    2. simple_list sl1; sl1.next = NULL; 没关系。只是不要尝试回读s 成员,因为这样做的行为是未定义

    3. simple_list *sl2; sl->next = sl2; 不,这也是未定义的行为,因为您正在读取未初始化的指针值。

    第三点非常微妙。大多数人都知道取消引用一个未初始化的指针是未定义的,但在大多数情况下读取一个指针也是未定义的。包括这个。

    【讨论】:

    • 涉及工会的事实在这里甚至都无关紧要。这与结构没有什么不同。
    【解决方案3】:
    simple_list *sl;
    

    声明指向simple_list的指针,不分配内存并且指针不指向有效的union

    sl->next = NULL; // core dumped, why?
    

    因为见上文。此联合实例不存在。

    【讨论】:

      【解决方案4】:

      你需要分配对象!

      simple_list* s1 = malloc(sizeof(simple_list));
      s1->next = NULL;
      

      【讨论】:

      • 使用malloc,而不是new;查看语言标签:[C].
      • 分配固定。谢谢。
      【解决方案5】:

      为指针s1分配内存。

      s1 = malloc(sizeof(union simple_list));
      

      此代码也不会编译。

      您需要为联合中的变量设置联合类型。

      union simple_list
      {
          union simple_list *next;
          int *s;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-26
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        • 2021-03-24
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        相关资源
        最近更新 更多