多个 ifstreams 访问冲突

发布于 2024-12-15 17:39:50 字数 859 浏览 2 评论 0原文

我尝试实现外部合并排序(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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

や三分注定 2024-12-22 17:39:50

据我所知,您实际上根本不需要 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;
    }       
}

As far as I can see, you don't really need an array of 2048 separate ifstreams 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:

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;
    }       
}
睫毛上残留的泪 2024-12-22 17:39:50

无法打开 2048 个文件,打开文件有操作系统限制

You cannot open 2048 files, there is an operating system limit for open files

三岁铭 2024-12-22 17:39:50

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 for 0xbaadf00d).

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. An ifstream is not a POD (Plain Old Data) type; it needs you to call its constructor in order to initialize properly. This is C++; use new and delete.

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...

泪意 2024-12-22 17:39:50

这是 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 个文件听起来不像一个很好的计划,但你可以稍后再想办法

This is C++.ifstream is non-POD, so you can't just malloc it: the instances need to get constructed

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;
    }       
}

Besides that, opening 2048 files doesn't sound like a good plan, but you can figure that out later

嘿哥们儿 2024-12-22 17:39:50

非 POD 对象数组是使用 new 分配的,而不是使用 malloc 分配的,否则构造函数不会运行。

您的代码正在获取未初始化的内存并将其“解释”为 ifstream,这显然会导致崩溃(因为类的构造函数尚未运行,甚至虚拟表指针也没有就位) 。

您可以在堆栈上分配所有对象:

ifstream file[2048];

或者如果堆栈占用是一个问题,则可以在堆上分配它们;

ifstream *file=new ifstream[2048];
// ...
delete[] file; // frees the array

(尽管您应该在此处使用智能指针以避免异常情况下的内存泄漏)

或者更好的是,使用 ifstreamvector (需要标头 ;):

vector<ifstream> file(2048);

不需要显式释放其元素。

(理论上,您可以使用malloc,然后使用放置new,但我根本不推荐它)


...此外,同时打开 2048 个文件感觉不是一个好主意......

Arrays of non-POD objects are allocated with new, not with malloc, otherwise the constructors aren't run.

Your code is getting uninitialized memory and "interpreting" it as ifstreams, 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:

ifstream file[2048];

or allocate them on the heap if stack occupation is a concern;

ifstream *file=new ifstream[2048];
// ...
delete[] file; // frees the array

(although you should use a smart pointer here to avoid memory leaks in case of exceptions)

or, better, use a vector of ifstream (requires header <vector>):

vector<ifstream> file(2048);

which do not require explicit deallocation of its elements.

(in theory, you could use malloc and then use placement new, but I wouldn't recommend it at all)


... besides, opening 2048 files at the same time doesn't feel like a great idea...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文