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