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

问题描述

假设我有以下代码

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*

没有理由认为这里的“存储区”将被覆盖;您将覆盖指针,而不是它所指向的内容,而是它所指向的是与文件相关的结构(stdio缓冲区,底层内核文件句柄的描述符等)。与为同一指针分配第二个malloc会覆盖第一个malloc所指向的内容相比,它不会覆盖所指向的内存。在这两种情况下,您都将丢失第一次资源获取,因为丢失了原始指针,而转而使用了新指针。

,

主要问题是,许多操作系统对每个进程可以拥有的多个打开文件具有 limit 限制,这是因为在内核数据结构中,每个文件实际上都有一个包含所有文件的数组进程中必须有足够的空间来容纳进程中的所有文件。

如果您覆盖指针,则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