指向结构的指针

时间:2011-01-28 07:05:12

标签: c

这将给出一个正确的输出,即使我没有分配内存并且已经在主内部声明了指向结构二的指针

    struct one
    {
    char x;
    int y;
    };

    struct two
    {
    char a;
    struct one * ONE;
    };

    main()
    {
    struct two *TWO;
    scanf("%d",&TWO->ONE->y);
    printf("%d\n",TWO->ONE->y);
    }

但是当我在main之外的结构之后声明一个指向2的指针时,我会得到分段错误,但为什么我之前没有得到分段错误

    struct one
    {
    char x;
    int y;
    };

    struct two
    {
    char a;
    struct one * ONE;
    }*TWO;


    main()
    {
    scanf("%d",&TWO->ONE->y);
    printf("%d\n",TWO->ONE->y);
    }

3 个答案:

答案 0 :(得分:3)

在这两种情况下,TWO指针,指向struct two类型的对象。

在案例1中,指针是狂野的,可以指向任何地方。

在案例2中,指针为NULL,因为它是全局的。

但在这两种情况下,指针都指向有效 struct two对象。您在scanf中的代码将此指针视为引用有效对象。这导致了不确定的行为。

答案 1 :(得分:2)

因为你正在做的是未定义的行为。有时它似乎有效。这并不意味着你应该这样做: - )

最可能的解释是如何初始化变量。当堆栈指针递减时,自动变量(在堆栈上)将获得堆栈上发生的任何垃圾。

函数外部的变量(如第二种情况)总是初始化为零(指针类型的空指针)。

这是你们两种情况之间的基本区别,但正如我所说,第一种情况纯属偶然。

答案 2 :(得分:1)

当声明全局指针时,它将被初始化为零,因此生成的地址将是您的系统可能读取或不可读的小数字。

声明自动指针时,其初始值可能更有趣。在这种情况下,无论运行时库在调用main()之前在堆栈上的那个点上留下什么,或者可能是编译器生成的堆栈帧设置代码中的剩余值。它有可能是一个保存的堆栈指针或帧指针,如果与小偏移一起使用,它是一个有效的指针。

所以无论如何,未初始化的指针确实有一些东西,一个值导致错误,而另一个值,现在,在你的系统上,没有。

那是,因为分段错误是操作系统的一种机制,而不是C语言。

故障是一种基于块的机制,可以为自己和其他程序分配一定数量的页面 - 每个页面都有几个K--它可以保护自己和其他程序的页面,同时允许程序自由统治。您必须偏离块上下文或尝试编写只读页面(即使您的页面)以生成错误。简单地打破语言规则并不一定足够。操作系统很高兴让你的程序行为不端,并且由于它的狂野引用而行为奇怪,只要它只读取和写入(或clobbers)本身。