I encountered a problem in my code, where I used the following sequence of map methods find(k), erase(k), find(k) and both times accessed the find's returned iterators first and second members.
This tought me to check properly against map.find(k) == map.end(). But what is happening behind the scenes if this is omitted?
Even though comparing find's returned iterator to .end() evaluates to true, it.first (old key) and it.second (random value) are still accessible.
Compiler version: g++ (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0
Minimal working example
#include <stdio.h>
#include <map>
int main(int argc, char const *argv[])
{
std::map<size_t, size_t> test_map;
test_map.insert(std::pair<size_t, size_t>(1,2));
test_map.insert(std::pair<size_t, size_t>(2,1));
printf("map<size_t, size_t> with %lu key-value pairs: (1,2) and (2,1).
Iterating over map:\n", test_map.size());
for (const auto &it : test_map)
{
printf("entry found - k: %lu, v: %lu\n", it.first, it.second);
}
size_t a = test_map.find(1)->first;
size_t b = test_map.find(1)->second;
printf("Called map.find(1): entry found - k: %lu, v: %lu\n", a, b);
test_map.erase(1);
printf("Called map.erase(1)\n");
if(test_map.find(1) == test_map.end())
printf("map.find(1) == test_map.end()\n");
if(test_map.find(2) == test_map.end())
printf("map.find(2) == test_map.end()\n");
size_t c = test_map.find(1)->first;
size_t d = test_map.find(1)->second;
printf("Called map.find(1): entry found - k: %lu, v: %lu\n", c, d);
printf("Iterating over map again:\n");
for (const auto &it : test_map)
{
printf("entry found - k: %lu, v: %lu\n", it.first, it.second);
}
return 0;
}
Output
./map_test
map<size_t, size_t> with 2 key-value pairs: (1,2) and (2,1). Iterating over map:
entry found - k: 1, v: 2
entry found - k: 2, v: 1
Called map.find(1): entry found - k: 1, v: 2
Called map.erase(1)
map.find(1) == test_map.end()
Called map.find(1): entry found - k: 1, v: 94380092077776 // k stays, v random
Iterating over map again:
entry found - k: 2, v: 1