【发布时间】:2013-01-18 04:47:48
【问题描述】:
FILE *file = fopen(argv[1], "r");
if(file != NULL){
char command[MAX_BUFFER];
while(fgets(command, MAX_BUFFER, file) != NULL){ //read line
//operations
}
fclose(file);
}
else write(fileno(stderr), ERROR_MESSAGE, strlen(ERROR_MESSAGE));
我正在开发一个非常基本的 UNIX shell 实现,它从文件中逐行读取和执行。从上面的代码中,我试图弄清楚为什么 fclose() 可能会失败,因为 valgrind 似乎告诉我我已经打开了这个文件描述符。
我是否正确假设泄漏摘要中的“仍然可达”568 字节以某种方式引用了失败的fclose()?
==25428== FILE DESCRIPTORS: 4 open at exit.
==25428== Open file descriptor 3: test
==25428== at 0x4F186B0: __open_nocancel (syscall-template.S:82)
==25428== by 0x4EAC628: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:233)
==25428== by 0x4EA1265: __fopen_internal (iofopen.c:93)
==25428== by 0x400C0C: main (in /home/Desktop/sh)
==25428==
==25428== Open file descriptor 2: /dev/pts/0
==25428== <inherited from parent>
==25428==
==25428== Open file descriptor 1: /dev/pts/0
==25428== <inherited from parent>
==25428==
==25428== Open file descriptor 0: /dev/pts/0
==25428== <inherited from parent>
==25428==
==25428== LEAK SUMMARY:
==25428== definitely lost: 0 bytes in 0 blocks
==25428== indirectly lost: 0 bytes in 0 blocks
==25428== possibly lost: 0 bytes in 0 blocks
==25428== still reachable: 568 bytes in 1 blocks
==25428== suppressed: 0 bytes in 0 blocks
【问题讨论】:
-
fclose() 有一个返回值。核实。如果它失败了,那么你可能会破坏堆栈。
-
用
-g标志编译会有帮助。 -
出于好奇,你为什么用
write(fileno(stderr), ERROR_MESSAGE, strlen(ERROR_MESSAGE))而不是fputs(ERROR_MESSAGE, stderr)? -
另外,为什么
fileno(stderr)而不是STDERR_FILENO?除非你在某个地方是freopen-ing stderr,否则这只会让维护者感到困惑。 -
@KeithThompson 对于这个实现,我将分叉一些进程,如果我没记错的话,fputs 会在内部缓冲类似于 printf 的字符串
标签: c shell unix file-io memory-leaks