此示例代码中的指针是否真的无效?

时间:2016-03-06 00:23:53

标签: c pointers iso c11

在这个示例代码中,while循环后指针真的可以无效,并且在编写代码时是否应该考虑到这一点? 或者C标准是否被误解和/或有缺陷?

#include <stdio.h>

int main(int argc, char **argv) {
    (void)argc;
    (void)argv;

    int *pointer;
    int object[1];

    pointer = object;
    printf("pointer -before: %p\n", (void*)pointer);

    do {
        int other_object[1];

        printf("a pointer \"just past\" other_object can look like: %p\n", (void*)(&other_object+1));
        printf("address of other_object: %p\n", (void*)&other_object);
    } while (0);
    puts("the lifetime of other_object has ended");
    printf("pointer -after: %p\n", (void*)pointer);
}

可能的输出(在我的机器上运行):

pointer -before: 0x7fff5f744ae4
a pointer "just past" other_object can look like: 0x7fff5f744ae4
address of other_object: 0x7fff5f744ae0
the lifetime of other_object has ended
pointer -after: 0x7fff5f744ae4

根据公认的答案,它似乎是一个不确定的指针: Array resizing and realloc function

以下文章中也提到了此问题,由于未定义的行为,更多示例代码会产生意外输出:

http://trust-in-soft.com/dangling-pointer-indeterminate/

两者都引用ISO中的这句话:“当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定。”

编辑: 根据有关int * vs void *

的注释更改了源代码

编辑: 更改了源代码以包含数组。

3 个答案:

答案 0 :(得分:6)

你正在解析这句话错误:

  

当指针指向(或刚刚过去)的对象到达其生命周期结束时,指针的值变得不确定

允许指针指向一个对象,如果是数组,则允许指向一个超过该数组最后一个元素的元素。

这意味着:如果指针指向一个对象,或者,如果它指向一个超过数组最后一个元素的元素,那么当该对象或该数组到达其生命周期的末尾时,它将变为不确定的

当一个刚刚碰到你指向的对象之后的对象到达其生命周期的终点,或指向的指针时,指针的值变得不确定并不是不确定的。对象本身在一个已经达到其生命周期结束的不同对象之后进入内存,这就是你似乎理解它的意思。在您的示例中,other_object紧跟在您指向的对象之前的内存地址,然后到达其生命周期的末尾,这一事实完全无关紧要,因为您所关注的对象实际指向 - 即object - 仍然存活,除了这个仍然活着的对象之外,你的指针决不会指向任何其他东西。

简短的回答:你正在阅读的内容&#34;刚刚过去&#34;那不存在。这仅仅意味着指向数组对象的指针增加到一个结尾的元素。它与任何其他完全不相关的对象没有任何关系,这些对象可能恰好碰巧跟在内存中的指向对象之后。

答案 1 :(得分:2)

您通过

调用了两个未定义的行为
  • 将错误类型的数据传递给printf()%p,要求void*,但您已通过int*
  • 减去两个不指向同一个数组对象元素的指针。

所以,任何事情都可能发生,指针可能是不确定的。

如果您没有调用未定义的行为,那么由于pointer的{​​{1}}地址object未更新,因此不会变得不确定在do语句之后仍然存在,它被分配给它。

答案 2 :(得分:2)

你问,

  

在这个示例代码中,while循环后指针真的可以无效,并且在编写代码时是否应该考虑到这一点?或者C标准是否被误解和/或有缺陷?

,显然基于此标准(略微脱离背景)来自标准:

  

&#34;当指针指向(或刚刚过去)的对象到达其生命周期的末尾时,指针的值变得不确定。&#34;

但标准并没有谈论一个指针偶然等于指向刚刚超过无关对象末尾的指针。相反,该文本指的是标准的明确规定,指向一个位置,越过一个数组的有效位置。当指针的有效性的基础依赖于它指向刚好超过对象的末尾时指针在该对象到达其生命周期结束时变得不确定时。通常,当有问题的指针是通过指向对象(或进入)对象的指针算法派生时,会出现这种情况。

所以不,在你的代码中,pointer的值在other_object到达其生命周期结束时不会变得不确定,尽管它相对于other_object期间指向return None的值寿命。