c++ - std::ifstream 因某种原因关闭?

标签 c++

我正在尝试打开将包含文件数据的 ifstreams,稍后可以读取这些数据。我正在尝试将 ifstreams 的 vector 传递给构造函数,但由于某种原因,当我循环遍历该 vector 时,所有引用都已关闭。但是,其他变量(数据流和元流)保持打开状态。

我在这里错过了什么?我来自非常深的 Java 背景,所以我仍在学习 C++

FileStore.h

//
// Created by Tom on 8/16/2017.
//

#ifndef CFS_FILESTORE_H
#define CFS_FILESTORE_H

#include <fstream>
#include <list>
#include "ByteBuffer.h"

class FileStore {

private:
    std::ifstream *data_stream;
    std::vector<std::ifstream *> index_streams;
    std::ifstream *meta_stream;

public:
    FileStore(std::ifstream *data, std::vector<std::ifstream *> indexes, std::ifstream *meta);
    ~FileStore() = default;

    int get_type_count();
    ByteBuffer read(int type, int id);
    int get_file_count(int type);

    static FileStore open(std::string &root);
};


#endif //CFS_FILESTORE_H

FileStore.cpp

//
// Created by Tom on 8/16/2017.
//

#include "FileStore.h"

FileStore::FileStore(std::ifstream *data, std::vector<std::ifstream *> indexes, std::ifstream *meta)
        : data_stream(data), index_streams(std::move(indexes)), meta_stream(meta) {

    std::cout << std::boolalpha << "Data Open : " << data_stream->is_open() << std::endl;
    std::cout  << "Meta Open : " << meta_stream->is_open() << std::endl;

    for (auto v : index_streams) {
        std::cout << "Index Open : " << v->is_open() << std::endl;
    }
}

int FileStore::get_type_count() {
    return 0;
}

ByteBuffer FileStore::read(int type, int id) {
    return ByteBuffer();
}

int FileStore::get_file_count(int type) {
    return 0;
}

FileStore FileStore::open(std::string &root) {
    std::ifstream data(root + "main_file_cache.dat2");
    if (!data.good())
        throw std::runtime_error("data file does not exist.");

    std::vector<std::ifstream *> indexes;
    for (int i = 0; i < 254; i++) {
        std::ifstream index(root + "main_file_cache.idx" + std::to_string(i));
        if (!index.good())
            break;

        indexes.push_back(&index);
    }

    std::ifstream meta(root + "main_file_cache.idx255");
    if (!meta.good())
        throw std::runtime_error("meta file does not exist.");

    return FileStore(&data, indexes, &meta);
}

输出

Data Open : true
Meta Open : true
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false
Index Open : false

最佳答案

    std::ifstream index(root + "main_file_cache.idx" + std::to_string(i));

这构造了一个 std::ifstream 对象。它以自动范围声明。

    indexes.push_back(&index);
}

这会将指向 std::ifstream 的指针推送到 indexes vector 中,但是因为 index 的自动范围随后立即结束, index 对象立即被销毁,其对应的文件被关闭。您在内部循环内的自动范围内声明了此 std::ifstream 对象。因此,对象在循环结束时被销毁。

随后的代码尝试取消引用这些存储在 indexes vector 中的指针,这些指针现在都是悬空指针。这会导致未定义的行为。

此外,indexes vector 按值传递,这导致 vector 被复制,这增加了困惑。

您需要重新阅读 C++ 书中的以下章节:

  • 解释自 Action 用域和动态作用域如何在 C++ 中工作的章节。

  • 本章解释了按引用传递函数参数和按值传递函数参数之间的区别及其含义。

关于c++ - std::ifstream 因某种原因关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45747404/

相关文章:

c++ - 我想通过lldb打印张量值

c++ - std::copy 用于多维数组

c++ - 在尝试使用递归查找集合的子集总数时,出现段错误

c++ - 旋转后字典序最小的字符串

c++ - 如何将 C++ 输入流定界符包含到结果标记中

c++ - Boost::Asio - 将套接字传递给二等舱

c++/ubuntu - 模板错误

c++ - 使用资源和 ROS (catkin_make) 使用 CMake 编译 Qt 项目

c++ - 为什么以这种方式处理成员函数?

c++ - 写一个日志收集器/阅读器,有什么好的设计吗?