如何检测FILE对象是否已关闭?

时间:2013-02-28 01:49:09

标签: c fclose

请参阅以下代码块,在调用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)
    }

3 个答案:

答案 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似乎是安全的。