首页 > 解决方案 > 如果我不关闭 ifstream 会导致内存泄漏吗?

问题描述

我已经研究了下面的问题,我明白我不必关闭ifstream,因为文件处理程序在退出范围时会自动关闭。[绝对没有内存泄漏] [我需要手动关闭 ifstream 吗?1

但在下面的代码中,文件处理程序是一个全局变量。因此,如果我们不手动关闭文件处理程序,我认为会导致内存泄漏。该假设是否正确或文件处理程序将由 c++ 自动处理?

#include <iostream>
#include <fstream>
#include <sstream>
#include <unistd.h>

using namespace::std;

ifstream config_file;
stringstream cmd;

int test() {
    config_file.open("config.file");
    cmd << config_file.rdbuf();
    string tmp = cmd.str();
    cout << " config buffer is " << tmp << "\n" <<endl; 
}

int main () {
    test();
    while (1) {
        test();
        sleep(1);
    }
}

有趣的是,cppcheck 也没有报告此文件中的内存泄漏。

cppcheck file.cpp 
//no error logs. 

有人可以确认上述代码中是否存在内存泄漏吗?

标签: c++linuxfilememory-managementmemory-leaks

解决方案


No.fstream是一个RAII对象,它会在范围结束时自动关闭。这意味着它最终会以任何方式为您关闭。

但是,您可以通过显式调用手动关闭它,close或者使用花括号将其简单地嵌套在范围内{}

出现另一种情况,如果要检查文件的关闭是否成功。比您还必须手动调用它。如果您想保证代码中的某个点是完全写入文件的,这很有用。

还要确保查看cppreference以获取更多信息。

linux 手册页close说明了以下内容,阅读起来也很有趣

不检查 close() 的返回值是一个常见但严重的编程错误。上一次 write(2) 操作的错误很有可能在最后的 close() 中首先报告。关闭文件时不检查返回值可能会导致数据无声丢失。这在 NFS 和磁盘配额中尤其明显。

成功关闭并不能保证数据已成功保存到磁盘,因为内核延迟写入。文件系统在流关闭时刷新缓冲区并不常见。如果您需要确保数据是物理存储的,请使用 fsync(2)。(此时这将取决于磁盘硬件。)

当同一进程中的其他线程中的系统调用可能正在使用文件描述符时,关闭文件描述符可能是不明智的。由于可以重用文件描述符,因此存在一些可能导致意外副作用的模糊竞争条件。

我不确定窗户上冲洗的情况。也许有人可以添加此信息。

进一步close()保证在您可以捕获和处理的失败时抛出异常。


推荐阅读