为什么不通过此程序打印垃圾值

时间:2017-01-21 12:20:43

标签: c++ c garbage-collection

以下程序可能会打印一些垃圾数据,因为字符串存储在函数getString()的堆栈帧中,并且在getString()返回后数据可能不存在。

#include <stdio.h>
char *getString()
{
  char str[] = "abc"; 
  return str; 
}     
int main()
{
  printf("%s", getString());  
  return 0;
}

输出:垃圾值。

那么为什么以下程序运行正常而不打印垃圾值。

#include<stdio.h>
int *fun()
{
    int i=50;
    int *p=&i;
    return p;
}

int main()
{
    int *q=fun();
    printf("%d",*q);
    return 0;
}

输出:50

这里p也是函数fun()中的指针,存储在堆栈段中。 我在这里很困惑。为什么输出是50而不是垃圾值?

感谢。

3 个答案:

答案 0 :(得分:2)

它显示堆栈中的值,因为该值尚未被其他内容覆盖。如果我们使用参数调用函数或创建一些堆栈变量,则打印的值将更改。下面打印1,而不是50,后者被覆盖。

void bar(int a, int b, int c)
{
    char buf[] = "string";
    printf("%d-%d-%d-%s\n", a, b, c, buf);
}

int *fun()
{
    int i=50;
    int *p=&i;
    return p;
}

int main()
{
    int *q=fun();
    bar(1, 2, 3);
    printf("%d\n",*q);
    return 0;
}

答案 1 :(得分:1)

Undefined behaviour表示语言标准没有为调用它的程序指定任何特定行为。您的程序有未定义的行为。具体的输出/行为完全是平台特定的,绝不可靠或有效;而且,它也包括“按预期工作”。

答案 2 :(得分:1)

我已经尝试过您的代码,但我的意思是

<强>的getString()

当getString()返回&#34; abc&#34;的字节时仍存储在先前的堆栈内存中。然而,CPU将准备调用printf,它会设置一个新的堆栈帧,从而覆盖&#34; abc&#34;使用特定于printf调用的数据。

<强>乐趣

fun的返回值存储在CPU累加器寄存器中,因此对printf的调用永远不会触及前一个堆栈帧的内存。