Home > database >  Why does std::distance doesn't work on iterator of unordered_map?
Why does std::distance doesn't work on iterator of unordered_map?

Time:02-05

I have this code:

#include <bits/stdc  .h>
#include <iostream>
using namespace std;

int main()
{
    unordered_map<int, int> umap;
    unordered_map<int, int>::iterator itr1, itr2;
    itr1 = umap.begin();
    itr2 = std::next(itr1, 3);
    cout << distance(itr2, itr1);
    return 0;
}

It compiles fine. But produces a Segmentation fault upon executing.

Why can't I find the distance between iterators?

CodePudding user response:

Result of std::next(itr1, 3) is beyond umap.end() and is the source of segfault. More of, umap.end() and umap.begin() would be invalidated by content of unordered_map. This would work but wouldn't allow use of std::distance anyway:

umap[0] = 3;
umap[1] = 4;
umap[2] = 5;
umap[3] = 5;
itr1 = umap.begin();
itr2 = std::next(itr1, 3);

unordered_map in an unordered container, doesn't have RandomAccessIterator and std::distance can't be used on its iterators.

CodePudding user response:

Your code has undefined behavior.

  1. umap is empty, then std::next(itr1, 3) returns an invalid iterator.

  2. Change the order of the arguments passed to std::distance.

InputIt must meet the requirements of LegacyInputIterator. The operation is more efficient if InputIt additionally meets the requirements of LegacyRandomAccessIterator

If InputIt is not LegacyRandomAccessIterator, the behavior is undefined if last is not reachable from first by (possibly repeatedly) incrementing first. If InputIt is LegacyRandomAccessIterator, the behavior is undefined if last is not reachable from first and first is not reachable from last.

E.g.

unordered_map<int, int> umap { {1,1}, {2,2}, {3,3} };
unordered_map<int, int>::iterator itr1, itr2;
itr1 = umap.begin();
itr2 = std::next(itr1, 3);
cout << distance(itr1, itr2);

LIVE

  •  Tags:  
  • Related