I’ve read conflicting ideas about what to do with large unordered maps, whether to allocate them on the heap vs the stack depending on its size being known/not at compile time. So hopefully someone can clear this up once and for all, because even as I’ve tried to move my large map to the heap, visual studio still warns me about it needing to be put on the heap.
defs.cpp
unordered_map<string, string>* Keywords = new unordered_map<string, string>({...});
defs.h
extern unordered_map<string, string>* Keywords;
The map has a size of 55k and is defined in the code and will never change as the app runs.
I repeat, the app never edits this map, it never adds to it, it never removes from it. the pairs are set in the defs.cpp file as described, before the code is compiled, the list is there. That’s why I put […] as placeholder to avoid pasting 1000+ lines of text.
I repeat, the example is exactly as described, this is the minimum reproductible example, there are no other parts required, this is 100% of the code you need.
It just needs to exist and be accessible to many parts of the app. From what I understand, the new
keyword should already be allocating on the heap?
Any help is much appreciated, thank you.
edit: for reference here’s the warning shown by Visual Studio
C6262: Function uses '55360' bytes of stack: exceeds /analyze:stacksize '16384'..
This allocation was for a compiler-generated temporary for 'struct std::pair<class std::basic_string<char,struct std::char_traits<char>, class std::allocator<char>>const,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char>>[865] at line XXX.
Consider moving some data to heap.
3
Answers
std::unordered_map<K,V>
must allocate the storage for its elements dynamically. To see why, you can for example consider thatsizeof(std::unordered_map<K,V>)
is a compile time constant. The elements are not stored directly within the map object but elsewhere.The same is true for most other containers (
std::array
is an exception). Hence, you almost never need to dynamically allocate the container.(And just assumed you did, then you would not use
new
and raw pointers.)I will risk a glimpse into the crystal ball. When you write
Then you actually have an enormous number of values between the brackets in
{...}
. These values are allocated on the stack no matter how you allocate theunordered_map
. Without knowing what you actually have there, it is next to impossible to suggest suitable workarounds.The compiler warning is not about the hash map, it’s about the initial data for the map, which you put inside your
({...})
. That code allocates an object of typestd::initializer_list<something>
, that object contains a long array, and that array is on the stack.Consider moving that initialization data somewhere else, here’s an example.