【问题标题】:Explanation for the output of the code代码输出说明
【发布时间】:2017-05-03 13:16:45
【问题描述】:
#include<stdio.h>
int *call();
int main()
{
    int *ptr;
    ptr=call();
    fflush(stdin);
    printf("%d",*ptr);
    return 0;
}
int * call()
{
    int x=25;
    ++x;
    return &x;
}

这段代码的输出是 0。我期待的是 26。
谁能解释一下原因?
我应该怎么做才能得到 26?

【问题讨论】:

标签: c pointers return lifetime fflush


【解决方案1】:

当你创建这个函数并调用它时,一个函数框架被推入堆栈,其中有一个空间用于声明一个 int 变量。现在你增加值并尝试返回它的地址。现在函数结束并删除堆栈帧。您正在尝试阅读它。它会随机返回一些东西。啊在其意义上不是随机的,但它返回的内容没有定义。你得到 0 ..有时可能得到 1 或 23 或 128749 或 -7364184。

要获得 26,您可能需要使用堆中的某些内容。(或声明一个可以存活足够长的数组)。 分配足够大的内存以容纳整数变量。然后操纵它。返回指向那个的指针。你会看到你想看到的。

注意:这是未定义的行为....当您在不同时间或不同机器上运行时,它可能会返回其他内容。 :)

我在这里提到的堆和堆栈是特定于实现的。堆是指我们分配的动态内存。

【讨论】:

    【解决方案2】:

    这里的问题是,从int * call(),您返回的是一个局部变量的地址,该地址在函数完成执行后变得无效。使用返回值调用undefined behavior

    你应该

    • 获取一个指针,使用malloc() 和family 等内存分配器函数分配内存,然后返回该指针。
    • 利用static 变量的整个生命周期贯穿整个程序执行。

    也就是说,不要使用fflush(stdin),因为它会调用未定义的行为。引用C11,第 7.21.5.2 章,(强调我的

    如果stream 指向一个输出流或更新流,其中最近的 未输入操作,fflush 函数会导致该流的任何未写入数据 被交付到宿主环境中写入文件; 否则,行为是 未定义。

    【讨论】:

      【解决方案3】:

      您不应该在stdin 上使用fflush(),它对输入流有未定义的行为。 You can Read about it here.

      返回一个局部变量的地址,函数执行完成后变为无效,会导致Undefined Behaviour。

      为了得到答案,我删除了 fflush(stdin) 并在 Windows 和 GCC 4.1.2 编译器上得到了输出 26

      正如@Anjaneyulu 评论的那样,它也可能依赖于编译器,但这是我在 Windows 上测试的屏幕截图。

      【讨论】:

      • 我没有通过删除 fflush 得到 26。
      • @drew 添加截图供参考。
      • @akhilesh1988 一旦函数返回它的堆栈帧就会破坏并产生未定义的行为,它也依赖于编译器
      • @Anjaneyulu 在删除fflush() 之后,我在 GCC 4.1.2 编译器上也得到了相同的结果,想知道这是怎么回事???但理论上,我同意,返回局部变量的地址可能会导致未定义的行为。
      猜你喜欢
      • 1970-01-01
      • 2012-08-12
      • 2016-04-17
      • 1970-01-01
      • 2012-06-25
      • 2019-08-31
      • 1970-01-01
      • 2013-09-12
      相关资源
      最近更新 更多