多个 ifstreams 访问冲突
我尝试实现外部合并排序(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;
}
}
但是,它崩溃了
sorting.exe 中 0x58f3a5fd (msvcp100d.dll) 处出现未处理的异常:0xC0000005:读取位置 0xcdcdcdfd 时出现访问冲突。
是否可以使用这么多打开的 ifstreams? 或者也许打开 2048 个 ifstreams 是一个非常糟糕的主意,并且有更好的方法来实现这个算法?
I try to realise an external merge sort (wiki) and I want to open 2048 ifstreams and read data to personal buffers.
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;
}
}
But, it crashes with
Unhandled exception at 0x58f3a5fd (msvcp100d.dll) in sorting.exe: 0xC0000005: Access violation reading location 0xcdcdcdfd.
Is it possible to use so much opened ifstreams?
Or maybe it is very bad idea to have 2048 opened ifstreams and there is a better way to realize this algorithm?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
据我所知,您实际上根本不需要 2048 个单独的
ifstream
数组。在任何给定时间您只需要一个 ifstream,因此每次迭代您都会关闭一个文件并打开另一个文件。销毁 ifstream 会自动关闭文件,因此您可以执行以下操作:As far as I can see, you don't really need an array of 2048 separate
ifstream
s here at all. You only need one ifstream at any given time, so each iteration you close one file and open another. Destroying an ifstream closes the file automatically, so you can do something like this:无法打开 2048 个文件,打开文件有操作系统限制
You cannot open 2048 files, there is an operating system limit for open files
VS 在调试模式下使用值
0xcdcdcdcd
来表示未初始化的内存(还要注意0xbaadf00d
)。您正在使用继承 C 语言的
malloc
,并且不调用构造函数,它只是为您提供一个指向数据块的指针。ifstream
不是 POD(普通旧数据)类型;它需要您调用其构造函数才能正确初始化。这是C++;使用新建
和删除
。更好的是,两者都不要使用;只需在堆栈上构建该内容并让它处理要使用的动态内存分配。
当然,这甚至没有涉及打开 2048 个文件的可怕想法,但您可能应该通过艰难的方式来学习这一点......
The value
0xcdcdcdcd
is used by VS in debug mode to represent uninitialized memory (also keep an eye out for0xbaadf00d
).You are using
malloc
which is of C heritage and does not call constructors, it simply gives you a pointer to a chunk of data. Anifstream
is not a POD (Plain Old Data) type; it needs you to call its constructor in order to initialize properly. This is C++; usenew
anddelete
.Better yet, don't use either; just construct the thing on the stack and let it handle dynamic memory allocation as it was meant to be used.
Of course, this doesn't even touch on the horrible idea to open 2048 files, but you should probably learn that one the hard way...
这是 C++。
ifstream
是非 POD,因此您不能只是对其进行 malloc:实例需要构造除此之外,打开 2048 个文件听起来不像一个很好的计划,但你可以稍后再想办法
This is C++.
ifstream
is non-POD, so you can't just malloc it: the instances need to get constructedBesides that, opening 2048 files doesn't sound like a good plan, but you can figure that out later
非 POD 对象数组是使用
new
分配的,而不是使用malloc
分配的,否则构造函数不会运行。您的代码正在获取未初始化的内存并将其“解释”为 ifstream,这显然会导致崩溃(因为类的构造函数尚未运行,甚至虚拟表指针也没有就位) 。
您可以在堆栈上分配所有对象:
或者如果堆栈占用是一个问题,则可以在堆上分配它们;
(尽管您应该在此处使用智能指针以避免异常情况下的内存泄漏)
或者更好的是,使用
ifstream
的vector
(需要标头;
):不需要显式释放其元素。
(理论上,您可以使用
malloc
,然后使用放置new
,但我根本不推荐它)...此外,同时打开 2048 个文件感觉不是一个好主意......
Arrays of non-POD objects are allocated with
new
, not withmalloc
, otherwise the constructors aren't run.Your code is getting uninitialized memory and "interpreting" it as
ifstream
s, which obviously results in a crash (because the constructor of the class hasn't been run not even the virtual table pointers are in place).You can either allocate all your objects on the stack:
or allocate them on the heap if stack occupation is a concern;
(although you should use a smart pointer here to avoid memory leaks in case of exceptions)
or, better, use a
vector
ofifstream
(requires header<vector>
):which do not require explicit deallocation of its elements.
(in theory, you could use
malloc
and then use placementnew
, but I wouldn't recommend it at all)... besides, opening 2048 files at the same time doesn't feel like a great idea...