我使用strfry编写了一个用anagram字符串编写的程序。它在默认标准输入时非常有效,但在与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并且没有检测到内存泄漏。
答案 0 :(得分:1)
重写此行
if (argc>1) fryend=fopen(argv[1],"r") ? fryend : stdin;
没有条件运算符。
也许像
if (argc > 1) {
FILE *tmp = fopen(argv[1], "r");
if (tmp) fryend = tmp;
}
答案 1 :(得分:0)
重定向stdin
a.out <test.txt
fgets()
可能会返回NULL
。
来自man fgets()
:
返回值
[...] fgets()在出错时或在没有读取任何字符的情况下发生文件结束时返回[s] [...] NULL。
反过来NULL
传递给strfry()
,
strfry(fgets(buf, 4095, fryend));
这不是一个好主意。
答案 2 :(得分:0)
fgets
返回NULL
。您应该使用此返回值而不是调用ferror
或feof
来控制循环。您还应该注意不要将NULL
指针传递给字符串函数。他们可能会优雅地处理这个问题,但通常不会。
所以你的循环应该是这样的:
while (fgets(buf, 4096, fryend)) {
strfry(buf);
fputs(buf, stdout);
}
我抛弃了memset
,因为fgets
的结果是以空值终止的,并且不会溢出缓冲区,所以你可以传递完整的4096字节长度。