使用Unordered_map进行堆栈溢出

时间:2012-11-21 20:09:29

标签: c++ stl stack-overflow

对于一个项目,我有一个开放表,我决定放入std::unordered_map。不幸的是,我只能对整个地图进行硬编码。所以,我决定将初始化分成多个文件。

class OpeningBook
{
public:
    OpeningBook();
private:
    std::unordered_map<std::string, int> opening_database_;
    void init1();
    void init2();
    void init3();
    void init4();
    void init5();
};

,构造函数只调用init函数:

OpeningBook::OpeningBook()
{
    init1();
    init2();
    init3();
    init4();
    init5();
}

所有这些看起来都像这样:

void OpeningBook::init1()
{
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-1000001100000-1-1000",5000));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-1000000100000-1-1100",5000));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-1000000100001-1-1000",5000));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-1000000100000-1-1010",5000));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-1000000100010-1-1000",5000));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-1000000100000-1-1001",5000));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-100000010000-11-1000",0));
    opening_database_.insert(std::pair<std::string, int>("0001000000-10000001000000-100000010000-10-1100",5000));
    // continues
}

但是,只要我的代码命中init1()中的左括号,就会抛出堆栈溢出异常。我认为堆栈溢出不会发生,因为堆上有unordered_map。这是怎么回事?我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:4)

您在每个initx()方法中插入了多少项?如果它有数千个,那么编译器可能会生成在堆栈上使用大量临时值的代码,并且只是要求比可用的堆栈空间更多。

尝试进一步分割初始化方法,看看是否能解决问题。

更好的方法可能是拥有一个包含初始化数据的表:

static const struct {
    const char *str;
    int n;
} DatabaseInitData[] = {
    {"0001000000-10000001000000-1000001100000-1-1000",5000},
    {"0001000000-10000001000000-1000000100000-1-1100",5000},
    {"0001000000-10000001000000-1000000100001-1-1000",5000},
    // etc
};

然后,在你的构造函数中:

OpeningBook::OpeningBook()
{
    for (int i = 0; i < sizeof(DatabaseInitData)/sizeof(DatabaseInitData[0]); i++) {
        opening_database_.insert(std::pair<std::string, int>(
            DatabaseInitData[i].str,
            DatabaseInitData[i].n));
    }
}