【问题标题】:The stdio filter crashed when piped管道时 stdio 过滤器崩溃
【发布时间】:2014-12-07 09:04:05
【问题描述】:

我已经编写了一个程序来使用 strfry 进行字谜字符串。它适用于默认标准输入,但与 stdio 重定向一起使用时会崩溃(函数,但最后会出现段错误):

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/mman.h"

int main(int argc,char *argv[]) {
    FILE *fryend=stdin;
    if (argc==1) goto mainloop;
    if (argc>1) fryend=fopen(argv[1],"r") ? fryend : stdin;

    mainloop:;
    char *buf=malloc(4096);
    while (!ferror(fryend)) {
        memset(buf,0,4096);
        strfry(fgets(buf,4095,fryend));
        fputs(buf,stdout);
    }
    free(buf);
    if (fryend!=stdin) fclose(fryend);
    return 0;
}

这里有什么问题?使用 GNU libc/GCC。运行 valgrind 并没有检测到内存泄漏。

【问题讨论】:

  • 您的fgets 呼叫始终在stdin 上工作。如果fryend是一个文件,你应该fclose它,否则Valgrind会抱怨。我不确定strfryNULL 输入上的行为。我认为将fgetsstrfry 调用分开并检查NULL 会更干净。
  • 附带说明:在我看来,让失败的fopen 默默地退回到stdin 并不是一个好的设计。
  • @M Oehm:它是一个stdio过滤器,就像rev,所以回退到stdin是合理的。
  • 好吧,也许吧。在此期间您对原始代码进行了所有更改,您是否仍然观察到相同的行为?
  • 观察力不错。将fgets(buf,4095,stdin) 更改为fgets(buf,4095,fryend) 应该会有所作为......

标签: c string stdio


【解决方案1】:

重写这一行

if (argc>1) fryend=fopen(argv[1],"r") ? fryend : stdin;

没有条件运算符。

可能是这样的

if (argc > 1) {
    FILE *tmp = fopen(argv[1], "r");
    if (tmp) fryend = tmp;
}

【讨论】:

    【解决方案2】:

    fgets 在到达文件末尾时返回NULL。你应该使用这个返回值而不是调用ferrorfeof 来控制你的循环。您还应该注意不要将NULL 指针传递给字符串函数。他们可能会优雅地处理这个问题,但通常不会。

    所以你的循环应该是这样的:

    while (fgets(buf, 4096, fryend)) {
        strfry(buf);
        fputs(buf, stdout);
    }
    

    我已经扔掉了memset,因为fgets 的结果是空终止的,不会溢出缓冲区,所以你可以传递完整的 4096 字节长度。

    【讨论】:

      【解决方案3】:

      重定向stdin

      a.out <test.txt
      

      fgets() 可能会返回 NULL

      来自man fgets()

      返回值

      [...] fgets() 返回[s] [...] NULL 错误或当文件结束而没有读取任何字符时。

      反过来NULL 被传递给strfry()

      strfry(fgets(buf, 4095, fryend));
      

      这不是一个好主意。

      【讨论】:

        猜你喜欢
        • 2020-11-05
        • 2023-03-24
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 2019-03-08
        • 2020-10-24
        • 2013-03-14
        • 1970-01-01
        相关资源
        最近更新 更多