请参阅以下代码块,在调用fclose之前,如何确保FILE对象未关闭? BTW,两次调用fclose是否安全?
FILE* f = fopen('test.txt')
//some code here, f may be closed by someone, but they may not set it to NULL
...
/// I want to make sure f is not closed before, how can I do it here?
if(...)
{
fclose(f)
}
答案 0 :(得分:4)
不,你必须自己跟踪它。这与告知是否已释放指向已分配块的指针的问题类似。由于指针不再有效,因此无法进行此类测试。这同样适用于FILE *
。关闭文件后,任何访问基础对象的尝试都会导致未定义的行为。
更新:
请注意,引用Linux手册页:
The behaviour of fclose() is undefined if the stream parameter is an illegal pointer, or is a descriptor already passed to a previous invo‐ cation of fclose().
请记住,未定义的行为并不意味着它会崩溃或不会“起作用”。这意味着不保证特定行为并且操作不安全。在FILE
之后访问fclose()
结构是一个非常糟糕的主意。
答案 1 :(得分:3)
无论何时在程序中的任何地方调用fclose(),都应该将FILE *文件指针设置为NULL,如下所示,稍后可以在文件末尾的清理过程中进行检查。
fclose(f)
f = NULL;
文件末尾的清理部分如下所示:
if (f != NULL)
{
fclose(f);
f = NULL;
}
答案 2 :(得分:-1)
粘贴fclose android-bionic的源代码:(fclose.c文件)
int fclose(FILE *fp)
{
int r;
if (fp->_flags == 0) { /* not open! */
errno = EBADF;
return (EOF);
}
FLOCKFILE(fp);
WCIO_FREE(fp);
r = fp->_flags & __SWR ? __sflush(fp) : 0;
if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
r = EOF;
if (fp->_flags & __SMBF)
free((char *)fp->_bf._base);
if (HASUB(fp))
FREEUB(fp);
if (HASLB(fp))
FREELB(fp);
fp->_r = fp->_w = 0; /* Mess up if reaccessed. */
fp->_flags = 0; /* Release this FILE for reuse. */
FUNLOCKFILE(fp);
return (r);
}
在关闭的FILE对象上调用fclose似乎是安全的。