无法预测以下程序的输出

Unable to predict the ouput of the following program

我对悬挂指针有一个想法。我知道下面的程序会产生悬空 pointer.But 我无法理解程序的输出

char *getString()
{
        char str[] = "Stack Overflow ";
        return str;
}
int main()
{
        char *s=getString();
        printf("%c\n",s[1]);
        printf("%s",s);    // Statement -1
        printf("%s\n",s);  // Statement -2
        return 0;
}

下面程序的输出是 吨 如果只有 Statement-1 存在,那么输出是一些抓取值 如果只有 Statement-2 则输出为新行

您的代码显示 undefined behaviour,因为您正在 return 获取局部变量的地址。

一旦 getString() 函数完成执行并且 returned.

就不存在 str

至于问题,

if only Statement-1 is there then output is some grabage values if only Statement-2 is there then output is new line

没有解释。一旦您的程序表现出未定义的行为,就无法预测输出,仅此而已。 [谁知道呢,它也可能会打印你的手机 phone 号码,或者一个守护进程可能会从我的鼻子里飞出来]

对于简单的逻辑部分,在printf()中添加一个\n将导致输出缓冲区立即刷新到输出。 [提示:stdout 是行缓冲的。]

解法:

您可以通过以下两种方式之一完成工作

  • 取一个指针,在getString()和return指针内部动态分配内存。 (我会推荐这个)。此外,free() 稍后在 main() 完成后。
  • make char str[] static 使范围不限于函数的生命周期。 (不太好,但还是可以的)

getString中的str是一个局部变量,分配在栈上,当函数returns时,它不存在了

我建议你这样重写getString()

char *getString()
{
        char str[] = "Stack Overflow ";
        char *tmp = (char*)malloc(sizeof(char)*strlen(str));
        memcpy(tmp, str, strlen(str));
        return tmp;
}

你还需要添加

free(s);

之前 return 0;

在我的例子中,指针 tmp 指向堆上的一块内存,它将一直存在到你的程序结束

你需要了解更多 stack and heap

除此之外,还有一种方法,使用静态变量代替

char *getString()
{
        static char str[] = "Stack Overflow ";
        return str;
}

PS:你得到以下陈述的正确答案printf("%c\n",s[1]);只是巧合。当您 return 退出函数时,操作系统没有时间做一些清理工作。但是会

数组被 return 编辑为指针,但数组本身是函数 return 之后的垃圾。只需使用静态修饰符。

关于s[1]的事情没问题。关键是,它是获得悬挂指针后的 first printf。因此,此时的堆栈仍然(可能)完好无损。你应该还记得堆栈只用于函数调用和局部变量(在 DOS 中它可以被系统中断使用,但现在不是这样了)。因此,在第一个 printf 之前(当 s[1] 被计算时),s[] 是可以的,但是之后 - 它不是(printf 代码搞砸了)。我希望,现在一切都清楚了。