我正在尝试打开包含文件数据的ifstreams,可以在以后读取。我试图将ifstreams的向量传递给构造函数,但由于某种原因,当我遍历向量时,所有引用都被关闭。但是,其他变量(数据流和元流)仍然是开放的。
我在这里缺少什么?我来自一个非常沉重的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
答案 0 :(得分:2)
std::ifstream index(root + "main_file_cache.idx" + std::to_string(i));
这构造了一个std::ifstream
对象。它以自动范围声明。
indexes.push_back(&index);
}
这会将指向std::ifstream
的指针推送到indexes
向量中,但由于index
的自动作用域会立即结束,所以index
对象会立即生效销毁,相应的文件被关闭。您在内部循环内的自动作用域中声明了此std::ifstream
对象。因此,对象在循环结束时被破坏。
indexes
向量中的指针,这些指针现在都是悬空指针。这会导致未定义的行为。
此外,indexes
向量通过值传递,这导致向量被复制,这增加了混乱。
您需要重新阅读C ++手册中的以下章节:
解释自动范围以及动态范围如何在C ++中工作的章节。
这一章解释了通过引用传递函数参数和按值传递它们之间的区别,以及这意味着什么。
答案 1 :(得分:0)
每个index
在其范围的末尾被销毁,使得它们的指针无效
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);
} // index is destroyed here
您应该更改它以使用new
创建它们(只需确保在您完成后删除它们)
std::vector<std::ifstream *> indexes;
for (int i = 0; i < 254; i++) {
std::ifstream* index = new std::ifstream(root + "main_file_cache.idx" + std::to_string(i));
if (!index->good())
break;
indexes.push_back(index);
}
或更好,请改用std::vector<std::unique_ptr<std::ifstream>>
和std::make_unique
。
当您从meta
返回时,data
和open
可能会遇到同样的问题。