无法预测以下程序的输出

时间:2015-02-03 12:11:47

标签: c arrays pointers

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

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,则输出为新行

3 个答案:

答案 0 :(得分:2)

您的代码显示undefined behaviour,因为您要返回本地变量的地址。

str函数完成执行并返回后,不存在getString()

至于问题,

  

如果只有Statement-1那么输出是一些grabage值,如果只有Statement-2那么输出是新行

没有解释。一旦您的程序显示未定义的行为,就无法预测输出,这就是全部。 [谁知道,它也可能打印你的手机号码,或者守护进程可能会从我的鼻子里飞出来]

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

<强>解决方案:

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

  • 取一个指针,在getString()内动态分配内存并返回指针。 (我推荐这个)。此外,free()稍后会在main()中完成。{/ li>
  • 制作char str[] static,以便范围不限于函数的生命周期。 (不太好,但仍然会做这个工作)

答案 1 :(得分:0)

str中的getString是一个局部变量,在堆栈上分配,当函数返回时,它不再存在。

我建议你像这样重写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]);只是巧合。从函数返回时,Opera System没有时间做一些干净的工作。但它会

答案 2 :(得分:0)

数组作为指针返回,但是从函数返回后数组本身就是垃圾。只需使用静态修饰符。

关于s [1]有什么问题。关键是,获取悬空指针后,它是第一个 printf。所以,此时的堆栈仍然(可能)完好无损。您应该记得,堆栈仅用于函数调用和局部变量(在DOS中它可以被系统中断使用,但现在情况并非如此)。因此,在第一个printf之前(当s [1]被计算时),s []是正常的,但是之后 - 它不是(printf'代码搞砸了)。我希望,现在很清楚。