几个ifstreams访问违规

时间:2011-11-16 23:30:31

标签: c++ heap access-violation ifstream

我尝试实现外部合并排序(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并且有更好的方法来实现这个算法?

5 个答案:

答案 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 ++;使用newdelete

更好的是,不要使用任何一种;只需在堆栈上构造东西,让它处理动态内存分配,因为它本意使用。

当然,这甚至没有触及打开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;
    }       
}