manatttta
manatttta

Reputation: 3130

Allocate large static std::unordered_map results in stack overflow

I am creating a static std::unordered_map as follows:

 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")},
...
...
});

This map has 5k+ entries, hence, on MSVC, allocating it results in stack overflow (I guess it pushes an std::initializer_list on the stack).

How can I allocate this, witout successive calls to insert()?

** Edit **

Tried to do this in an allocater function with successive calls to std::unordered_map::insert() but is overflows the stack anyway when the allocator function is called (it probably pushes all the elements onto the stack anyway)

Upvotes: 1

Views: 569

Answers (1)

Seems the problem is only with regards to where the initializer for the map resides. I suggest you move it to a static array, and use the appropriate unordered_map constructor to create the 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));

BTW, identifiers beginning with a pair of leading underscores are reserved for the implementation, always. I therefore removed them my code sample.

Also, I don't know why you need to dynamically allocate the map, but C++ function local static objects are always initialized only when control first passes through them. Since std::unordered_map already allocated memory by itself, the extra allocation seems redundant. You may want to change you map to a value instead:

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

Upvotes: 3

Related Questions