没有 fclose() 的 FILE * 重新分配可以吗?

Is FILE * reassignment without fclose() okay?

假设我有以下代码:

FILE *x = fopen("story.txt",r);
if(x!=NULL)
{
    x = fopen("story.txt",wb); /* <- Does this waste/leak memory ?? */
    /* ... do something .... */
    /* if(fclose(x)==EOF)...else... */
}
else
{
    printf("story.txt does not exist\n");
}

在这里,我将指针重新分配到在内存中为 story.txt 创建缓冲区的位置,而不是 fclose(x) ,假设因为它是一个指针,内存区域将只是 覆盖到'new'缓冲区。这个假设准确吗?我是否在泄漏或浪费内存,或者这种方法是否合适?

您刚刚泄露了一个文件句柄。如果你做得足够多,你将 运行 没有打开的文件句柄来分配,并且所有打开文件的尝试都将失败。不要那样做。 fclose 你的 FILE*s.

这里没有理由认为“内存区”会被覆盖;您正在覆盖 指针 ,而不是它指向的内容,它指向的是与文件相关的结构(stdio 缓冲区、底层内核文件句柄的描述符等.).它不会覆盖指向的内存,就像将第二个 malloc 分配给同一个指针会覆盖第一个 malloc 指向的内容一样;在这两种情况下,您都在通过丢失原始指针以支持新指针来泄漏第一次资源获取。

主要问题是许多操作系统对每个进程可以打开的文件数有 限制,这是因为在每个进程的内核数据结构必须有足够的 space 用于进程中的所有文件。

如果你覆盖指针,在C中没有垃圾回收(如果不是你自己做的,通常=永远不会),所以系统不会知道指向的FILE结构指针应该是空闲的——这将导致内存泄漏。但更严重的泄漏是有限操作系统资源的泄漏。

这种情况会在您退出程序后自行解决 - 所有未关闭的文件都将被关闭并刷新。但是把 fclose 放在那里真的有那么难吗:

FILE *x = fopen("story.txt", r);
if (x != NULL)
{
    fclose(x);
    x = fopen("story.txt", wb); // <- this certainly does not leak any more