我正在尝试一些指针和功能交互,并发现了这种行为。第一个printf打印100但第二个printf打印0!
有人可以帮助我理解为什么吗?
void ptr_change (int **p)
{
int y = 100;
*p = &y;
}
int main ()
{
int x = 7;
int *p = &x;
ptr_change(&p);
printf("\nPtr = %d", *p);
printf("\nPtr = %d", *p);
return 0;
}
编译:
gcc ptr2.c
运行并输出输出:
./a.out
Ptr = 100
Ptr = 0
答案 0 :(得分:3)
y
是一个自动局部变量,在函数返回后将不再存在,并且您将自动局部变量的地址分配给指针。
在main
函数中,您将取消引用不再指向有效位置的指针。这会调用未定义的行为。一旦有未定义的代码行为,就不能指望任何好的东西。
答案 1 :(得分:2)
您从过程返回自动变量的地址。函数返回后,变量不再有效。接下来发生的事情称为未定义行为,但是,对英特尔机器的解释,例如VC2008是:
ptr_change(&p);
这会在p
中放置局部变量y
的地址。从函数ptr_change
返回后,函数使用的堆栈空间被释放。
printf("\nPtr = %d", *p);
第一个printf重新使用ptr_change
之前使用的堆栈空间。它将2个参数压入堆栈。第一个参数覆盖函数调用中&p
使用的堆栈空间。 y
尚未被覆盖。 printf的*p
参数获取此值并将其推送到堆栈。对printf的调用现在会覆盖int y
。
printf("\nPtr = %d", *p);
由于int y
已在之前的cal到printf中被覆盖,因此对printf的调用会打印出垃圾。
请注意,任何其他形式的未定义行为都是可能的!
答案 2 :(得分:1)
中
y
的值
void ptr_change (int **p)
{
int y = 100;
*p = &y;
}
仅作为automatic variable
在堆栈上临时存在。
一旦函数返回该位置不再有效。
比较以下程序,该程序将指针传递给变量a
并初始化指针p
。
#include<stdio.h>
void ptr_change2 (int **p, int *a)
{
*p = a;
}
int main ()
{
int x = 7;
int z = 8;
int *p = &x;
printf("\nPtr = %d", *p);
ptr_change2(&p,&z);
printf("\nPtr = %d", *p);
return 0;
}
输出:
Ptr = 7
Ptr = 8
答案 3 :(得分:-3)
*p = &y
不正确,您将y的地址指定为p。
的值试试这个:
p = &y
他们现在将拥有相同的基地址。
y = 100;
然后打印p
的指针值printf("%d", *p);