为什么第三个printf会打印未定义的值? #包括 int main() { int i=10; int*p=&i; foo&p; printf(“%d”,*p); printf(“%d”,*p); } 无效foo(整数**const p) { int j=11; *p=&j; printf(“%d”,**p); }
最终输出是什么为什么第三个printf会打印未定义的值? #包括 int main() { int i=10; int*p=&i; foo&p; printf(“%d”,*p); printf(“%d”,*p); } 无效foo(整数**const p) { int j=11; *p=&j; printf(“%d”,**p); },c,pointers,C,Pointers,最终输出是什么 为什么第三个printf将打印未定义的值?第三个printf正在打印正确的值。问题在于j是一个自动局部变量,一旦函数返回,它就不再存在。因此,main中的p没有指向您期望的位置,最终您的程序调用未定义的行为 可能的解决方案: 1.在j #include <stdio.h> int main() { int i = 10; int *p = &i; foo(&p);
为什么第三个printf将打印未定义的值?第三个
printf
正在打印正确的值。问题在于j
是一个自动局部变量,一旦函数返回,它就不再存在。因此,main
中的p
没有指向您期望的位置,最终您的程序调用未定义的行为
可能的解决方案:1.在
j
#include <stdio.h>
int main()
{
int i = 10;
int *p = &i;
foo(&p);
printf("%d ", *p);
printf("%d ", *p);
}
void foo(int **const p)
{
int j = 11;
*p = &j;
printf("%d ", **p);
}
void foo(int **const p)
{
static int j = 11;
*p = &j;
printf("%d ", **p);
}
二,。动态分配j
#include <stdio.h>
int main()
{
int i = 10;
int *p = &i;
foo(&p);
printf("%d ", *p);
printf("%d ", *p);
}
void foo(int **const p)
{
int j = 11;
*p = &j;
printf("%d ", **p);
}
void foo(int **const p)
{
static int j = 11;
*p = &j;
printf("%d ", **p);
}
在
foo
中,为*p
分配一个值,该值指向堆栈上已分配给foo
的位置。当foo
返回时,堆栈弹出,该位置可以自由重用-但是main
中的p
仍然指向它
当您第一次在main
中调用printf
时,恰好堆栈上的该位置尚未(尚未)写入任何新数据,因此读取*p
将为您提供11
,您将其与调用printf
的其他内容一起推到堆栈上,它成功地打印了11
。但是调用printf
的操作会更改堆栈上的数据,包括(可能)p
(在main
中)指向的位置,因为堆栈是在foo
返回后弹出的
然后,第二次调用再次使用该堆栈位置的数据,第一次调用printf
可能会更改这些数据
这个故事的寓意是:不要保留指向已弹出堆栈位置的指针。foo中的“i”是堆栈分配的,在从内存中退出之前,所有东西都可以正常工作,因此foo的printf可以正常工作,而第二个printf和第三个printf可以正常工作,直到foo的整数i从内存中退出。这是一个系统问题,可能是最后两个printf工作或不工作。如果您想让它们一直工作,则需要在调用void foo()时使用mallo堆分配foo的整数i,在堆栈上创建新的堆栈帧,因此int j=11作为局部变量进入此堆栈框架。假设int j在地址0x000ffd处,值为10,那么*p现在存储这个地址。现在,当该函数返回堆栈展开时会发生什么
在堆栈展开期间,它完成所有清理工作。因此,该堆栈帧中的所有数据都会被销毁,因此现在地址0x000ffd可能具有相同的值或不同的值,但变量j现在与它没有关联。因此它的未定义行为所有三个printf都在打印11。您的预期输出是什么?对于哪个标准的C?C99或更早的版本?什么未定义的值?问题是
foo
给主p分配了一个局部变量j的地址。按照C标准,j
的值,因此在离开foo
后,*p
的值是未定义的@Marian:这是一个答案,不是一个注释。:-)