调试标志编译时出现“virtual memory exhausted: Cannot allocate memory”错误。

3

我遇到了以下代码的错误(error.cpp):

#include <map>
#include <functional>
#include <vector>

int main()
{
    std::map<
        int, std::map< std::string,
        std::map<std::string, std::map<std::string, std::map<std::string,
        std::map<std::string, std::map<std::string, std::map<std::string,
        std::map<std::string, std::map<std::string, std::map<std::string,
        std::map<std::string, std::map<std::string, std::map<std::string,
        std::map<std::string, std::map<std::string, std::map<std::string,
        std::map<std::string, std::map<std::string, std::map<std::string,
        std::map<std::string, std::string>
            > > >
            > > >
            > > >
            > > >
            > > >
            > > >
            > >                                         oups;

}

在使用调试标志进行编译时:

g++ error.cpp -g -o error

我的系统是运行在虚拟机上的Ubuntu 18.04版本,使用的编译器为g++ 7.5.0版本。RAM内存大小为5GB,Swap空间大小为2.5GB,硬盘剩余空间只有1GB。

这种情况正常吗?是个bug吗?还是有限制?

针对以上代码,(c++14)有什么更好的替代方案?


4
“更好”可能意味着更不荒谬的东西吧? - Mansoor
4
好消息!Visual Studio同意了... fatal error C1060: compiler is out of heap space 的翻译:致命错误!编译器已用完堆空间。 - Retired Ninja
1
有趣的是,使用方面不提,有人能够对作者关于发生了什么以及为什么会发生的问题提供实际答案吗?我的意思是,20个嵌套模板并不算太多,是否存在某些分支导致指数级增长? - Quimby
1
听起来你只想要一个以字符串结构体为键的映射表。 - Sneftel
1
@jav - 我并没有暗示标准存在问题。这是你代码中的问题。标准中的非规范内容是建议或(在这种情况下)推荐,不意味着需要任何诊断。基本上,如果你编写的代码超出了这样的建议(就像你现在这样),那么你可以预期出现更多的问题,比如编译器崩溃。你看到在调试版本中出现问题而在“不使用调试标志”时没有出现问题,有很多可能的解释。 - Peter
显示剩余8条评论
1个回答

3

那个定义中有8+7+6个字符串,对吧?所以我会说你手上拥有的是一个21元关系。为什么不尝试:

constexpr const std::size_t my_arity = 21;
std::unordered_set<std::array<std::string, my_arity>> oups;

改为“而不是”?


确切地说,我应该使用这个版本。不过我需要用map代替unordered_set。为了接受答案,我想我还需要知道错误原因。对社区来说那将更有用。 - jav
1
好的,我猜测一个地图是在堆上为几个节点创建了存储空间。假设有4个节点。此外,随着您进入更深层级,您将最深层级上使用的存储量与该因素相乘。所以,4^21 = 2^42,这需要大量的内存! - einpoklum
@einpoklum:现在我们必须记住,只有在使用调试标志时才会出现错误。没有标志,编译非常快,没有问题。 - jav
已接受,因为我使用了类似的代码。希望有一天我们能够找到原始代码失败的确切原因。 - jav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接