I_Need_Coffee
I_Need_Coffee

Reputation: 59

Accessing last element of map using map.end()

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

int main()
{
    map <int, int > m;
    map <int, int>::iterator it1, it2;
    m[1] = 1;
    m[2] = 1;
    m[3] = 1;
    it1 = m.end()--;
    it2 = --m.end();

    cout << it1->first << " " << it1->second << endl;
    cout << it2->first << " " << it2->second << endl;
}

Output:

3 -1778731776 
3 1

The iterators are pointing to the same key but are giving different values. Why? I am unable to understand this odd behaviour. How does the post-decrement and the pre-decrement work here?

Upvotes: 1

Views: 3537

Answers (1)

The iterators are pointing to the same key

No they do not. m.end()--; is post decrement. Its semantic is to decrement the return value of m.end() as a side-effect, but return the original value unchanged. So it1 == m.end() and you get undefined behavior by dereferencing it.

It compiles successfully due to an unfortunate side-effect of operator++ being a member function of a user defined type (the iterator). You can call it even on an r-value like m.end(), while the built-in post-decrement expects an l-value.

So even though iterators model pointers, they aren't quite the same. To contrast, this program:

char* foo();

int main() {
  foo()--;
}

will produce an error on foo()--, because foo() is an r-value pointer, and we cannot decrement it.

Upvotes: 8

Related Questions