【问题标题】:emplace_back + ofstream + windows -> bug?emplace_back + ofstream + windows -> 错误?
【发布时间】:2015-12-18 20:35:51
【问题描述】:

下面的代码尝试在 ./out 文件夹中创建 800 个文件。在带有 g++ 4.9.2 的 Linux Debian 上,该程序可以正常工作。但是在带有 g++ 5.2.0 (MinGW) 的 Windows 7 或 8 上,程序在 509 个文件处停止。该错误似乎是在类 Task 的构造函数中使用 emplace_back 和 ofstream 的组合。是bug吗?

//g++ -std=c++11 main.cpp
#include <sstream>
#include <fstream>
#include <list>
#include <iostream>

#ifdef _WIN32
    #include <io.h>
#else
    #include <sys/stat.h>
#endif

using namespace std;

int i;

struct Task
{
    ofstream out;
    Task(string file_name): out(file_name)
    {
        if(!out) {cout<<i<<"\n"; exit(1);}
    }
};

int main()
{       
    #ifdef _WIN32
        string output_folder = ".\\out";
        mkdir(output_folder.c_str());
        output_folder+="\\";
    #else
        string output_folder = "./out";
        mkdir(output_folder.c_str(),S_IRWXU);
        output_folder+="/";
    #endif

    list<Task> ltask;
    for(i=0; i<800; i++)
    {
        ostringstream os;
        os<<output_folder<<i;
        ltask.emplace_back(os.str());
    }
    return 0;
}

【问题讨论】:

标签: c++


【解决方案1】:

这是对打开文件数量的限制(在 Windows 或运行时库或其他地方)...用以下代码更改上面代码中的循环会导致相同的结果:

list<ofstream*> l;
for(i=0; i<800; i++)
{
    ostringstream os;
    os<<output_folder<<i;
    l.push_back(new ofstream(os.str()));
}
for(auto p: l) delete p;

【讨论】:

  • 那么如果他写完就关闭文件就OK了?
  • 问题是同时打开的文件数。在 Windows 中,每个进程不能大于 512。上面带有“delete”的例子表明emplace_back被怀疑是错误的。
  • @Sergey 你说得对,我删除了帖子。感谢您的评论。
【解决方案2】:

this question

默认情况下,CRT(由 C++ 标准库使用)限制为 512 个同时打开的文件描述符。您将 3 用于 stdin、stdout 和 stderr,剩下 509。(您的任务不只是创建文件;它们使它们保持打开状态。)

如果您在创建文件后将其关闭,那就没问题了。您还可以提高限制(在另一个问题中解释)或使用 Windows 文件句柄,其中有更高的限制。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 2018-11-06
    • 2023-04-05
    相关资源
    最近更新 更多