我尝试实现外部合并排序(wiki),我想打开2048 ifstreams并将数据读取到个人缓冲区。
ifstream *file;
file = (ifstream *)malloc(2048 * sizeof(ifstream));
for (short i = 0; i < 2048; i++) {
itoa(i, fileName + 5, 10);
file[i].open(fileName, ios::in | ios::binary); // Access violation Error
if (!file[i]) {
cout << i << ".Bad open file" << endl;
}
if (!file[i].read((char*)perfile[i], 128*4)) {
cout << i << ". Bad read source file" << endl;
}
}
但是,它与
崩溃了sort.exe中0x58f3a5fd(msvcp100d.dll)的未处理异常:0xC0000005:访问冲突读取位置0xcdcdcdfd。
是否可以使用这么多打开的ifstreams? 或者也许是非常糟糕的想法让2048打开ifstreams并且有更好的方法来实现这个算法?
答案 0 :(得分:4)
这是C ++。ifstream
是非POD,所以你不能只是malloc它:实例需要构造
ifstream file[2048];
for (short i = 0; i < 2048; i++) {
itoa(i, fileName + 5, 10);
file[i].open(fileName, ios::in | ios::binary); // Access violation Error
if (!file[i]) {
cout << i << ".Bad open file" << endl;
}
if (!file[i].read((char*)perfile[i], 128*4)) {
cout << i << ". Bad read source file" << endl;
}
}
除此之外,打开2048个文件看起来不是一个好计划,但你可以稍后解决
答案 1 :(得分:4)
VS在调试模式下使用值0xcdcdcdcd
来表示未初始化的内存(同时请留意0xbaadf00d
)。
您正在使用具有C遗产的malloc
并且不调用构造函数,它只是为您提供指向一大块数据的指针。 ifstream
不是POD(普通旧数据)类型;它需要你调用它的构造函数才能正确初始化。这是C ++;使用new
和delete
。
更好的是,不要使用任何一种;只需在堆栈上构造东西,让它处理动态内存分配,因为它本意使用。
当然,这甚至没有触及打开2048文件这个可怕的想法,但是你应该知道这一点很难......
答案 2 :(得分:4)
非POD对象的数组分配有new
,而不是malloc
,否则构造函数不会运行。
您的代码正在获取未初始化的内存并将其“解释”为ifstream
,这显然会导致崩溃(因为即使虚拟表指针已到位,类的构造函数也未运行)
您可以在堆栈中分配所有对象:
ifstream file[2048];
如果堆栈占用是一个问题,则在堆上分配它们;
ifstream *file=new ifstream[2048];
// ...
delete[] file; // frees the array
(尽管你应该在这里使用智能指针以避免在出现异常时发生内存泄漏)
或更好地使用vector
ifstream
(需要标题<vector>
):
vector<ifstream> file(2048);
不需要显式释放其元素。
(理论上,你可以使用malloc
,然后使用展示位置new
,但我根本不会推荐它。
...此外,同时打开2048个文件并不是一个好主意......
答案 3 :(得分:0)
您无法打开2048个文件,打开文件存在操作系统限制
答案 4 :(得分:0)
据我所知,你根本不需要一个2048个单独ifstream
的数组。在任何给定时间,您只需要一个 ifstream,因此每次迭代都会关闭一个文件并打开另一个文件。销毁ifstream会自动关闭文件,因此您可以执行以下操作:
for (short i = 0; i < 2048; i++) {
itoa(i, fileName + 5, 10);
ifstream file(fileName, ios::in | ios::binary);
if (!file) {
cout << i << ".Bad open file" << endl;
}
if (!file.read((char*)perfile[i], 128*4)) {
cout << i << ". Bad read source file" << endl;
}
}