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

Gáb*_*lla 0 c iso pointers 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);
}
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

根据一个公认的SO答案,它似乎是一个不确定的指针: 数组调整大小和重新分配函数

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

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

两者都引用了ISO中的这句话:"当指针指向(或刚刚过去)的对象到达其生命周期的末尾时,指针的值变得不确定."


编辑:根据有关int*vs void*的注释更改了源代码


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

Cro*_*man 6

你正在解析这句话错误:

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

允许指针指向一个对象,并且在数组的情况下,允许指向一个超过该数组的最后一个元素的元素.

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

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

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

  • @BuellaGábor`就在"之前".实际上就在之前.不.那是编译器和架构的依赖.该标准没有说明不同对象(不是同一阵列的元素)的地址如何相互关联或不相关.事实上,正如我在另一篇评论中已经说过的那样,该标准使UB甚至试图比较不相关对象的地址. (2认同)