будет ли ifstream вызывать утечку памяти, если я не закрою? - PullRequest
0 голосов
/ 28 августа 2018

Я посмотрел на вопрос ниже, где я понял, что мне не нужно закрывать ifstream, так как обработчик файла закрывается автоматически при выходе из области. [определенно нет утечки памяти] [ Нужно ли вручную закрывать ifstream? 1

Но в приведенном ниже коде обработчик файла является глобальной переменной. Так что, если мы не закроем обработчик файлов вручную, я думаю, что это приведет к утечке памяти. Это предположение искажает или обработчик файла будет автоматически обрабатываться с ++?

#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 голосов
/ 28 августа 2018

Нет. Деструктор std::ifstream закрывает поток неявно . Область действия не имеет значения в этом случае - деструктор в конечном итоге будет вызван.

0 голосов
/ 28 августа 2018

Деструктор файлового потока по умолчанию закрывает файл независимо.

0 голосов
/ 28 августа 2018

Нет. fstream - это объект RAII , он закрывается автоматически в конце области. А это значит, что он в конечном итоге для вас закрыт.

Однако вы можете закрыть его вручную, явно вызвав close или просто вложив его в область видимости, используя фигурные скобки {}.

Другая ситуация возникает, если вы хотите проверить, удалось ли закрыть файл. Чем вы также должны вызвать его вручную. Это полезно, если вы хотите гарантировать точку в коде, где файл написан полностью.

Также не забудьте проверить cppreference для получения дополнительной информации.

Страница man linux для close гласит следующее, что также интересно прочитать

Не проверка возвращаемого значения close () является распространенной, но, тем не менее, серьезной ошибкой программирования. Вполне возможно, что ошибки в предыдущей операции write (2) сначала сообщаются в финальном закрытии (). Не проверка возвращаемого значения при закрытии файла может привести к потере данных без вывода сообщений. Это особенно заметно в случае NFS и дисковой квоты.

Успешное закрытие не гарантирует успешного сохранения данных на диск, поскольку ядро ​​откладывает запись. Обычно файловая система не очищает буферы при закрытии потока. Если вам необходимо убедиться, что данные физически хранятся, используйте fsync (2). (Это будет зависеть от аппаратного обеспечения диска на данный момент.)

Возможно, неразумно закрывать файловые дескрипторы, когда они могут использоваться системными вызовами в других потоках в том же процессе. Поскольку файловый дескриптор может быть повторно использован, существуют некоторые неясные условия гонки, которые могут вызвать непреднамеренные побочные эффекты.

Я не уверен насчет ситуации с флешем на окнах. Может быть, кто-то может добавить эту информацию.

Далее close() гарантирует исключение при сбое, которое вы можете перехватить и обработать.

...