代码输出 11,11,未定义值 .......请解释一下?
#include <stdio.h>
void f(int **const p);
int main()
{
int i = 10;
int *p = &i;
f(&p);
printf("%d ", *p);
printf("%d ", *p);
}
void f(int **const p)
{
int j = 11;
*p = &j;
printf("%d ", **p);
}
答案 0 :(得分:8)
它是undefined behavior,因为你设置*p
指向一个局部变量,一旦函数退出所有局部变量超出了范围,这会给你一个悬空指针。
真正发生的事情是,以前的函数调用会重用以前由局部变量j
占用的内存,因此您将打印函数设置该内存的任何值。 / p>
答案 1 :(得分:6)
下面:
*p = &j;
j
的范围小于p
的范围。函数f
返回时,p
中存储的值不再有效。因此未定义的行为。
答案 2 :(得分:1)
变量的范围是定义它的函数的局部。在你的情况下,j是函数f的局部变量。变量j在函数f之外不再可见。因此p变为悬空指针。如果你期望输出为11 11 11然后你必须将j声明为静态变量。
答案 3 :(得分:1)
一旦退出函数f()
,变量j
就会超出范围,但指针p
仍然指向该内存地址。这是未定义的行为。
简化的代码内联版本,评论发生了什么:
int main()
{
int *p; //create pointer
{
int j = 11; //create j in local scope
p = &j; //set p to point at j (refered to as address A from now)
printf("%d ", *p);//print value at A "11 "
} //j goes out of scope
printf("%d ", *p); /*print value at A "11 11 "
***UB: as memory at A is not used to store j any more,
printf() can use it to store variables for its own use*/
printf("%d ", *p); /*print value at A "11 11 GARBAGE"
***UB: as memory at A is not used to store j any more,
the previous printf() call touched A at some point
changing the contents (and thus the read value)*/
}
说实话,我很惊讶第一个printf()
的调用在输出之前没有破坏内存。
您不能依赖第二个printf
输出'正确的值'。即使在这个简单的例子中,所看到的行为仅由实现决定,而不同的编译器很可能会以不同的方式处理它。
只是通过更改代码,非常可能输出会发生变化,例如,在printf
可能覆盖内存并停止输出正确之前声明一个新变量。