【问题标题】:Allocate large static std::unordered_map results in stack overflow分配大的静态 std::unordered_map 导致堆栈溢出
【发布时间】:2017-07-11 13:22:10
【问题描述】:

我正在创建一个静态std::unordered_map,如下所示:

 auto* __epsgMap__ = new std::unordered_map <int/*EPSG*/, CRS::Info> ({

{3819, CRS::Info("HD1909","+proj=longlat +ellps=bessel +towgs84=595.48,121.69,515.35,4.115,-2.9383,0.853,-3.408 +no_defs")},
{3821, CRS::Info("TWD67","+proj=longlat +ellps=aust_SA +no_defs")},
{3824, CRS::Info("TWD97","+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs")},
{3889, CRS::Info("IGRS","+proj=longlat +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +no_defs")},
{3906, CRS::Info("MGI 1901","+proj=longlat +ellps=bessel +towgs84=682,-203,480,0,0,0,0 +no_defs")},
{4001, CRS::Info("Unknown datum based upon the Airy 1830 ellipsoid","+proj=longlat +ellps=airy +no_defs")},
...
...
});

这个映射有 5k+ 个条目,因此,在 MSVC 上,分配它会导致堆栈溢出(我猜它会将 std::initializer_list 推送到堆栈上)。

如果没有连续调用insert(),我该如何分配这个?

** 编辑 **

尝试在分配器函数中执行此操作并连续调用std::unordered_map::insert(),但在调用分配器函数时无论如何都会溢出堆栈(它可能无论如何都会将所有元素推入堆栈)

【问题讨论】:

  • 我不清楚是什么导致了这个问题。只是将参数推送到堆栈的过程会导致它溢出吗?
  • 这张地图的内容看起来可以通过 const 初始化存储在有序数组中。
  • @FrançoisAndrieux 我猜。这在 GCC/LLVM 下不会发生。
  • 数据排序了吗?地图是否在运行时接收新条目?
  • @RetiredNinja 这听起来像是一个糟糕的选择,因为它没有存储在堆栈中(根据 std::unorderd_map 的设计)。只是临时入栈的初始化列表

标签: c++ c++11


【解决方案1】:

似乎问题仅在于地图的初始化程序所在的位置。我建议你将它移动到一个静态数组中,并使用适当的unordered_map 构造函数来创建地图:

static std::pair<int/*EPSG*/, CRS::Info> const map_init[] = {

{3819, CRS::Info("HD1909","+proj=longlat +ellps=bessel +towgs84=595.48,121.69,515.35,4.115,-2.9383,0.853,-3.408 +no_defs")},
//...
};

auto* epsgMap = new std::unordered_map <int/*EPSG*/, CRS::Info>(std::begin(map_init), std::end(map_init));

顺便说一句,以一对前导下划线开头的标识符始终保留用于实现。因此,我删除了我的代码示例。

另外,我不知道为什么需要动态分配映射,但 C++ 函数本地静态对象总是只有在控制第一次通过它们时才会初始化。由于std::unordered_map 已经自己分配了内存,额外的分配似乎是多余的。您可能希望将映射更改为一个值:

static std::unordered_map<int/*EPSG*/, CRS::Info> epsgMap(
   std::begin(map_init), std::end(map_init)
);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-21
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多