C++ map showing values as 0 for all keys

Viewed 1862

I am inserting number from a vector in map with key as the number and value as it's (index + 1). But when I print the contents of the map, value being shown is 0 though I pass interger i.

// taking input of n integers in vector s;
vector<int> s;
for(int i=0;i<n;i++){
    int tmp;cin>>tmp;
    s.push_back(tmp);
}
//creating map int to int
map<int,int> m;
bool done = false;
for(int i=1;i<=s.size();i++){
   //check if number already in map
   if (m[s[i-1]]!=0){
       if (i-m[s[i-1]]>1){
          done = true;
          break;
       }
    }
    // if number was not in map then insert the number and it's index + 1
    else{
          m.insert({s[i-1],i});
    }
}
for(auto it=m.begin();it!=m.end();it++){
    cout<<endl<<it->first<<": "<<it->second<<endl;
}

For input n = 3 and numbers as 1 2 1 in vector s, I expect the output to be

1: 1
2: 2

but output is

1: 0
2: 0

Why 0? What's wrong?

2 Answers

Your code block following the comment:

// check if number already in map

is logically faulty, because operator[] will actually insert an element, using value initialisation(a), if it does not currently exist.

If you were to instead use:

if (m.find(s[i-1]) != m.end())

that would get rid of this problem.


(a) I believe(b) that value initialisation for classes involve one of the constructors; for arrays, value initialisation for each item in the array; and, for other types (this scenario), zero initialisation. That would mean using your method creates an entry for your key, with a zero value, and returns that zero value

It would then move to the else block (because the value is zero) and try to do the insert. However, this snippet from the standard (C++20, [map.modifiers] discussing insert) means that nothing happens:

If the map already contains an element whose key is equivalent to k, there is no effect.


(b) Though, as my kids will point out frequently, and without much prompting, I've been wrong before :-)

std::map::operator[] will create a default element if it doesn't exist. Because you do m[s[i-1]] in the if condition, m.insert({s[i-1],i}); in else branch will always fail.

To check if key is already present in map use either find(), count() or contains() (if your compiler supports C++20)

//either will work instead of `if (m[s[i-1]]!=0)`
if (m.find(s[i-1]) != m.end()) 
if (m.count(s[i-1]) == 1)
if (m.contains(s[i-1])) //C++20
Related