为什么即使从堆栈中分配内存后输出也不是垃圾?

时间:2016-09-11 08:04:52

标签: c

#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'中然后输出是正确的。我有的困惑是,即使在解除分配后为什么输出是正确的?

2 个答案:

答案 0 :(得分:3)

您不应该认为您的输出是正确的。它看起来是正确的,但你应该认为这是巧合。您正在观察未定义的行为,理论上这意味着任何都可能发生,例如产生您期望的值,格式化您的硬盘,或者(如某些人喜欢的那样)说)导致恶魔飞出你的鼻子。指针 指向垃圾;虽然它似乎指向有效的东西,但您无法保证您观察到的行为将来会再现。

至于输出可能出现为“正确”的原因,在解除分配时通常不会自动清除内存。这样做是额外的工作,通常不是默认情况下完成的事情。另一种可能性是,由于您正在访问“狂野”指针,因此会返回一个与您最初分配的值相符的随机值。 (正如他们所说,破碎的时钟每天正确两次。)

答案 1 :(得分:0)

堆栈已预先分配并保留用于当前执行的线程。只是因为某些东西被解除分配,并不意味着它会自动被抹掉。当后续调用其他函数时,很可能会替换这些数据。