【发布时间】: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。同样,两个编译器产生相同的结果。
这是我的问题:
原来的答案是否正确?它如何(不)正确?
为什么以及如何对
printf的注释调用更改p的内容?还是我没抓住重点?
【问题讨论】:
-
“11”是“垃圾”的合法值。
-
取消引用指向不再“存在”的数据的指针会导致未定义的行为。它可能似乎可以工作,或者它可能崩溃,或者它可能导致nasal demons。
-
由于在对象的生命周期结束后访问对象,程序的行为未定义。
-
分析未定义的行为在大多数情况下是无用的任务。
-
@RaymondChen 投票结束时,请注意语言标签。