我调查了以下问题,我知道我不必关闭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.
有人可以确认上面的代码中是否存在内存泄漏?
答案 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)
文件流的默认析构函数无论如何都会关闭文件。