如果我不关闭,ifstream是否会导致内存泄漏?

时间:2018-08-28 15:09:29

标签: c++ linux file memory-management memory-leaks

我调查了以下问题,我知道我不必关闭ifstream,因为从范围退出时文件处理程序会自动关闭。 [绝对没有内存泄漏] [Do I need to manually close an 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. 

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

3 个答案:

答案 0 :(得分:4)

不。 fstream是一个RAII对象,它会在范围末尾自动关闭。这意味着它最终将以任何方式对您关闭。

但是,您可以通过显式调用close手动将其关闭,也可以使用大括号{}将其简单地嵌套在作用域中。

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

还请确保签出cppreference以获得更多信息。

linux man-page for close指出以下内容,这也很有趣

  

不检查close()的返回值是一个常见但严重的编程错误。很有可能首先在最后的close()中报告了先前write(2)操作的错误。关闭文件时不检查返回值可能会导致数据静默丢失。使用NFS和磁盘配额时尤其如此。

     

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

     

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

我不确定Windows刷新的情况。也许有人可以添加此信息。

另外close()保证在失败时引发异常,您可以捕获并处理该异常。

答案 1 :(得分:2)

不。 std::ifstream的析构函数关闭流implicitly。在这种情况下范围并不重要-析构函数将最终被调用。

答案 2 :(得分:1)

文件流的默认析构函数无论如何都会关闭文件。