【问题标题】:How pointers to out-of-scope-variable behave in C? [duplicate]指向范围外变量的指针在 C 中如何表现? [复制]
【发布时间】:2017-05-04 17:00:02
【问题描述】:

我需要分析以下程序的输出:

#include "stdio.h"
void foo(int **const p)
{
    int j = 11;
    *p = &j;
    printf("%d ", **p);
}
int main()
{
    int i = 10;
    int *p = &i;
    foo(&p);
    printf("%d ", *p);
    printf("%d ", *p);
}

我知道实际上没有人这样写,但尽管如此。我希望它输出类似11 [garbage] [garbage] 的东西,结果却发现答案是11 11 [undefined value]。我决定旋转一下。

#include "stdio.h"
void foo(int **p)
{
    int j = 11;
    *p = &j;
    printf("1:-");
    printf("%d-", **p);
}
int main()
{
    int i = 10;
    int *p = &i;
    foo(&p);
    /* printf("2:-"); */ 
    printf("%d-", *p);
    printf("3:-");
    printf("%d-", *p);
}

这将在我的平台上提供1:-11-11-3:-0-(macOS 10.12.2,在 Apple LLVM 版本 8.0.0 (clang-800.0.42.1) 和 Homebrew gcc 6.2.0 上进行了测试)。

如果我取消注释 printf("2:-"); 行,我会得到 1:-11-2:-0-3:-0-。第二个调用以不同的方式打印p。同样,两个编译器产生相同的结果。

这是我的问题:

  1. 原来的答案是否正确?它如何(不)正确?

  2. 为什么以及如何对printf 的注释调用更改p 的内容?还是我没抓住重点?

【问题讨论】:

  • “11”是“垃圾”的合法值。
  • 取消引用指向不再“存在”的数据的指针会导致未定义的行为。它可能似乎可以工作,或者它可能崩溃,或者它可能导致nasal demons
  • 由于在对象的生命周期结束后访问对象,程序的行为未定义。
  • 分析未定义的行为在大多数情况下是无用的任务。
  • @RaymondChen 投票结束时,请注意语言标签。

标签: c pointers printf


【解决方案1】:

指针的值是不确定的,引用该对象会调用未定义的行为,根据6.2.4p2对象的存储持续时间

[...] 如果对象在其生命周期之外被引用,则行为未定义。当指针指向的对象到达其生命周期结束时,指针的值变得不确定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2020-06-24
    • 2013-01-29
    相关资源
    最近更新 更多