【问题标题】:What is the exact meaning of "fflush(stdin)" in the following program? [duplicate]以下程序中“fflush(stdin)”的确切含义是什么? [复制]
【发布时间】:2014-03-24 23:56:15
【问题描述】:

我通过一些网站搜索并找到了一个悬挂指针的程序。我找到了一个在 TC 中完美执行的最佳程序。但是由于我对 fflush(stdin) 的怀疑,我无法理解程序的全部含义。所以请说出以下程序的含义和其他程序:

    #include<stdio.h>
    int *call(void);
    int main(void) {
      int *ptr;
      ptr = call();
      fflush(stdin);
      printf("%d", *ptr);
      return 0;
    }
    int *call(void) {
      int x = 25;
      ++x;
      return &x;
    } 

【问题讨论】:

  • 没有@Banthar。这个问题并不具体。但我的疑问特别是在上面的程序中。
  • 也是UB,因为它返回并使用自动变量的地址。

标签: c pointers


【解决方案1】:

fflush 的目的是清理或刷新由于它的参数产生的缓冲区。例如

char ch [10];
scanf("%s",ch); // here scanf finishes taking input after tou pressed enter and that enter may still remain in keyboardbuffer
fflush(stdin); //flushes that enter which is in keyboard buffer

现在假设如果我们使用 FILE 指针将 ch 写入文件,我们将在文件上获得所需的输出。 如果你不使用

fflush(stdin);

假设您想将 ch 写入文件,然后每次写入时,由于 enter 的效果在键盘缓冲区中并且不需要,因此它将写入文件中的新行。

【讨论】:

  • 这是未定义的行为,即使不是,给定代码中也没有输入操作,因此使用fflush 清除剩余输入绝对没有意义。我也不确定您在第一句话中所说的“由于其论点而产生”是什么意思。
  • “由于它的参数而生成”我的意思是我们使用我们要清理的缓冲区的参数
  • 我通过我自己的例子指定了 fflush 的功能
  • 声称 fflush(stdin) 有某种行为。但是标准没有定义fflush 在输入流上的行为,所以它实际上是未定义的行为。请注意,fflush(stdin) 在许多平台上根本不会执行任何操作,因此您的示例不会执行您声称在这些平台上执行的操作。
  • 那你被教错了。看看这个:ideone.com/bvW2m5。如果fflush 照你说的做(在所有平台上),next 的值在这里应该是'e',但它是'\n'
【解决方案2】:

fflush(stdin) 通常没有意义,因为它是未定义的行为(有关原因的更详细描述,请参见答案中换行符下方的this answer)。

fflush() 刷新缓冲区,当它在这样的上下文中使用时,它通常用于尝试刷新输入缓冲区stdin。因此,没有任何“待定”缓冲区处于干净状态。

特别是在这个程序中,它根本没有意义。没有输入操作,所以什么都不做*.

*当然,“未定义的行为”意味着任何事情都可能发生,因此它可以某事,但如果平台支持这一点并且它确实将缓冲区清除为预计,对代码不会有明显影响。

【讨论】:

  • 嗯,正如你所说,它是 UB,所以它很可能会做一些事情(比如鼻恶魔等等)。但是在fflush(stdin) 清空流中缓冲的输入的平台上,它确实不会在这里做任何事情。
  • @sepp2k - 你知道,我以为在我写完之后......但后来我想“不,没有人会打电话给我”。 ;) 是的,你当然是正确的,它可以做 something 因为它是 UB。
【解决方案3】:

在这种特定情况下,fflush(stdin) 用于覆盖ptr 的内容。任何函数都可能覆盖悬空堆栈指针。看起来fflush(stdin) 是任意选择的。我得到了类似的结果:

#include<stdio.h>

int* call(void);
int* dummy(void);

int main(){
    int *ptr;
    ptr=call();
    printf("%d\n",*ptr);
    dummy();
    printf("%d\n",*ptr);
    return 0;
}

int* dummy(void) {
    int x=0;
    return &x;
}

int* call(void){
    int x=25;
    ++x;
    return &x;
}

【讨论】:

  • 这段代码像原始代码一样被破坏:UB 由于使用了超出范围的对象的地址(通过&amp;x)。
  • @Jens 我相信这就是重点。它应该展示悬空指针的危险。
猜你喜欢
  • 2010-11-05
  • 2014-05-19
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 2014-01-15
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多