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

int main() {
    unordered_map< int,list<pair<int,int>>> adjList;
    adjList[1].push_back(make_pair(2,2));
    adjList[1].push_back(make_pair(4,-1));
    adjList[0].push_back(make_pair(1,3));
    for(pair<int,int> neighbour : adjList[1]){
        pair<int,int>* it = &neighbour;
       std::advance (it,1);
       cout<<it->first<<" ";    //1)showing random value twice instead of 4(-1113715584 -1113715584) 
    }
    for (list<pair<int,int>>::iterator i=adjList[1].begin(); i!=adjList[1].end(); i++)
        cout<<*i.first;         //2)list<std::pair<int, int> >::iterator'has no member named 'first'
    }
}
  1. it is showing correct value(2,4) without {std::advance (it,1);} which is supposed to take iterator to next head but it is showing some random value twice every time.
  2. error : 'std::__cxx11::list<std::pair<int, int> >::iterator' {aka 'struct std::_List_iterator<std::pair<int, int> >'} has no member named 'first' cout<<*i.first;

Jarod42
  • 203,559
  • 14
  • 181
  • 302

1 Answers1

3

You are invoking undefined beahvior here:

   pair<int,int>* it = &neighbour;
   std::advance (it,1);
   cout<<it->first<<" ";

It is the same problem as with

   std::pair<int,int> p;
   std::pair<int,int>* ptr = &p;
   ptr += 1;                     // ok-ish 
   std::cout << ptr->first;      // undefined behavior !!

You can only increment a pointer to get a valid pointer when the pointer points to an element in an array. Incrementing the pointer to a single object is fine, because sloppy speaking a single pair can be considered as an array of size 1 and it is allowed to get a pointer one past the last element of an array. However, you shall not dereference that pointer.

A std::list does not store its elements in contiguous memory. You could get a pointer to an element in eg a std::vector and advance it to get a pointer to the next element. However, the address you are taking is actually not to the element in the list. When you write

for(pair<int,int> neighbour : adjList[1]){

Then neighbour is a copy of the element in the list. It is a single pair, completely unrelated to the list. If you had used

for(pair<int,int>& neighbour : adjList[1]){

Then neighbour would be a referece to the element in the list, but your code would still be wrong for the reasons explained above.


The second error is due to a typo. *i.first is *(i.first) but you want (*i).first or i->first.


Last, but not least, consider that std::make_pair has much fewer use-cases than it had before C++11. Your case isn't one of them, you can simply write:

adjList[1].push_back({2,2});

Moreover, I suggest you to read Why should I not #include <bits/stdc++.h>? and Why is “using namespace std;” considered bad practice?.

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185