【问题标题】:How to access members of a pointer to structure in c? [duplicate]如何在c中访问指向结构的指针的成员? [复制]
【发布时间】:2021-12-24 15:39:31
【问题描述】:

您能否解释一下,为什么这个程序有效:

#include<stdio.h>

int main()
{
    struct first{
        char *name;
        int a;
    };

    struct second{
        struct first *second;
        int z;
    };

    struct first *FIRST, C;
    FIRST = &C;
    
    struct second *SECOND, b;
    SECOND = &b;
    
    
    SECOND->second->a = 9;

    printf("%d", SECOND->second->a);


    return 0;    
}

虽然不是这样:

#include<stdio.h>

int main()
{
    struct first{
        char *name;
        int a;
    };

    struct second{
        struct first *second;
        int z;
    };

    //struct first *FIRST, C;
    //FIRST = &C;
    
    struct second *SECOND, b;
    SECOND = &b;
    
    
    SECOND->second->a = 9;

    printf("%d", SECOND->second->a);


    return 0;    
}

简而言之,你能告诉我为什么我需要在上面的代码中添加这两个注释掉的行吗?我是这个领域的初学者。所以,如果你能帮助我,那就太好了。

提前致谢!

【问题讨论】:

  • 您的第一个代码也不起作用。 SECOND-&gt;second 无处可去,所以 SECOND-&gt;second-&gt;a = 9; 是未定义的行为。你可能忘记了SECOND-&gt;second = FIRST;。始终读取编译器输出:godbolt.org/z/zrT87r3W7
  • 这两个例子都不正确,您没有初始化指针以指向有效的东西。查看链接的副本以及What is undefined behavior and how does it work?

标签: c pointers struct initialization undefined-behavior


【解决方案1】:

这两个程序都有未定义的行为。

在类型为 struct second 的对象 b 中

struct second *SECOND, b;

第二个具有指针类型的数据成员未初始化并且具有不确定的值。所以在这个语句中取消引用这个指针

SECOND->second->a = 9;

导致未定义的行为。

如果对象 b 被初始化为例如,第一个程序可能是正确的

struct second *SECOND, b = { FIRST };

【讨论】:

    【解决方案2】:

    简答:因为你的代码是非法的,所以编译器无法理解你的意思。

    在这两个代码片段中,SECOND-&gt;second 指向无处(您没有为其赋值)并且通过SECOND-&gt;second-&gt;a,您正在取消引用SECOND-&gt;second。它被称为未定义的行为(UB)。说明如下。

    C 的 ISO 标准努力为编译器留出空间来优化您的代码。他们的努力包括为编译器提供一些强有力的假设(不应该发生的事情)。

    ISO 标准不要求编译器对相同类型的 UB 执行一致。它假装这种规则的变化从未发生过,因此它可以愉快地调整您的代码以更快地运行。它不一定不能打印 9,但你不能依赖它,因为它可能会失败甚至导致难以诊断的问题。(实际上你的两个代码片段在我的环境中都无法打印 9。)

    如果您打开(确切地说不要关闭)编译器的警告选项,它会警告您。 不要这样写代码。

    【讨论】:

    • 谢谢,但是,您能更正这段代码吗?这会对我有所帮助,因为我是这个领域的新手。而且,这对我来说更容易理解。
    • 关于“在您的情况下, second::second 是 struct first * 类型,但您为其分配了 struct second * 值”:哪一行代码可以做到这一点?显示的代码中没有一个名为 second 的成员被赋予任何值。
    • 我的错。我没有彻底检查代码。在您的代码中 SECOND->second 没有分配任何值,并且 deref 这样的指针是非法的。
    猜你喜欢
    • 2019-08-30
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 2014-06-09
    • 2022-11-01
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多