#include<stdio.h>
char* call();
void hello();
void hello2();
int main()
{
char * p=call();
hello();
hello2();
printf("%c\n",*p);
return 0;
}
void hello()
{
printf("HELLO\n");
}
void hello2()
{
printf("hello2\n");
}
char* call()
{
char a = 's';
char *b = &a;
return b;
}
上述程序提供以下输出:
您好
hello2
s
我所知道的是当我从main调用call()函数时,堆栈帧将在堆栈中分配,当call()函数返回地址时,内存将被解除分配,但是当我尝试打印值时存储在变量'a'中然后输出是正确的。我有的困惑是,即使在解除分配后为什么输出是正确的?
答案 0 :(得分:3)
您不应该认为您的输出是正确的。它看起来是正确的,但你应该认为这是巧合。您正在观察未定义的行为,理论上这意味着任何都可能发生,例如产生您期望的值,格式化您的硬盘,或者(如某些人喜欢的那样)说)导致恶魔飞出你的鼻子。指针 指向垃圾;虽然它似乎指向有效的东西,但您无法保证您观察到的行为将来会再现。
至于输出可能出现为“正确”的原因,在解除分配时通常不会自动清除内存。这样做是额外的工作,通常不是默认情况下完成的事情。另一种可能性是,由于您正在访问“狂野”指针,因此会返回一个与您最初分配的值相符的随机值。 (正如他们所说,破碎的时钟每天正确两次。)
答案 1 :(得分:0)
堆栈已预先分配并保留用于当前执行的线程。只是因为某些东西被解除分配,并不意味着它会自动被抹掉。当后续调用其他函数时,很可能会替换这些数据。