3

请参阅以下代码块,我如何确保 FILE 对象在调用 fclose 之前未关闭?顺便说一句,两次调用 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)
    }
4

3 回答 3

6

不,您必须自己跟踪它。这类似于判断指向已分配块的指针是否已被释放的问题。由于指针不再有效,因此无法进行此类测试。这同样适用于FILE *。关闭文件后,任何访问底层对象的尝试都会导致未定义的行为。

更新:

请注意,引用 Linux 手册页:

如果流参数是
非法指针,或者是已经传递给先前调用的描述符
fclose() 的阳离子。

请记住,未定义的行为并不意味着它会崩溃或它不会“工作”。这意味着不保证任何特定的行为并且操作是不安全的。之后访问FILE结构fclose()是一个非常糟糕的主意。

于 2013-02-28T01:56:28.217 回答
3

每当您在程序中的任何位置调用 fclose() 时,都应将 FILE* 文件指针设置为 NULL,如下所示,您可以稍后在文件末尾的清理过程中对其进行检查。

fclose(f)
f = NULL;

文件末尾的清理部分如下所示:

if (f != NULL)
{
    fclose(f);
    f = NULL;
}
于 2013-02-28T01:51:54.150 回答
-1

粘贴android-bionic的fclose源代码:(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 似乎是安全的。

于 2013-02-28T02:29:02.543 回答