I have a C++ code where I am instantiating an unordered_map and then printing it's values using cout. This works fine. But, when I try to run this in gdb and print the values of the unordered_map, this gives me error. Below, is the code snippet:
std::unordered_map<std::string,int> mymap = {
{ "Mars", 3000},
{ "Saturn", 60000},
{ "Jupiter", 70000 } };
std::cout<< mymap.at("Mars");
std::cout<< mymap["Mars"];
Both the cout statements above print the unordered_map value for key "Mars". However, when I use gdb and then try using below statements to print the value of mymap at key "Mars", I get errors.
(gdb) print mymap.at("Mars")
Cannot resolve method std::unordered_map<std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, int,
std::hash<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > >, std::equal_to<std::basic_string<char,
std::char_traits<char>, std::allocator<char> > >,
std::allocator<std::pair<std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const, int> > >::at to any overloaded instance
(gdb) print mymap["Mars"]
Cannot resolve function operator[] to any overloaded instance
I do not get what is wrong when I use gdb.
I have tried using whatis mymap, in gdb, to see if mymap is present in current context and it gives that it is present. Also, I tried initializing an int variable and printing it in gdb and it prints it. I do not understand what is the problem with unordered_map.
I am using below statement to generate executable
gsrivas4@TitanX01:~/lcode1$ g++ -std=gnu++11 -O0 -g test1.cpp -o test1.out
To check for the existence of a particular key in the map, the standard solution is to use the public member function find() of the ordered or the unordered map container, which returns an iterator to the key-value pair if the specified key is found, or iterator to the end of the container if the specified key is not ...
Iterating over a map by using STL Iterator: By creating an iterator of std::map and initializing it to the starting of map and visiting upto the end of map we can successfully iterate over all the elements of map.
Because unordered_map containers do not allow for duplicate keys, this means that the function actually returns 1 if an element with that key exists in the container, and zero otherwise.
map is used to store elements as key,value pairs in sorted order. unordered_map is used to store elements as key,value pairs in non-sorted order.
The problem you are facing is that std::unordered_map<std::string,int>::at(key)
expects a key of type std::string
, not a const char*
literal. This means that
you'd like to create a temporary std::string object, before passing it to at()
.
Creating a temporary object from within GDB does not work well for me, and I may be missing something but this is what I get:
(gdb) p std::string("Mars")
A syntax error in expression, near `"Mars")'.
(gdb) p 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'("Mars")
$9 = -161888904
So it does not seem possible to construct an std::string
object inside GDB without
some additional C++ code, so just add to your C++ code:
std::string make_string(const char *x)
{
return x;
}
And now everything works:
(gdb) p mymap.at(make_string("Mars"))
$1 = (std::unordered_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >::mapped_type &) @0x60005e5f0: 3000
(gdb) p mymap.at(make_string("Jupiter"))
[New Thread 14608.0x16f4]
$2 = (std::unordered_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >::mapped_type &) @0x60005e650: 70000
But
(gdb) p mymap[make_string("Jupiter")]
Could not find operator[].
This does not work because it was never instantiated. What your code instantiated by:
std::cout<< mymap["Mars"];
was T& operator[]( Key&& key );
which is tricky to invoke from GDB.
Had you instantiated T& operator[]( const Key& key );
instead, then things would
have fared better.
The solution: instantiate the operator[](const std::string &)
variant in your C++ code. So here
is the new code:
std::string make_string(const char *x)
{
return x;
}
int main()
{
std::unordered_map<std::string,int> mymap = {
{ "Mars", 3000},
{ "Saturn", 60000},
{ "Jupiter", 70000 } };
std::string mars{"Mars"};
std::cout<< mymap.at(mars);
std::cout<< mymap[mars];
}
With this, debugging becomes possible:
print mymap.at(make_string("Jupiter"))
print mymap[make_string("Jupiter")]
just work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With