Is it possible for std::multimap::equal_range to return incorrect results?

前提是你 提交于 2020-01-05 14:17:49

问题


Good afternoon, I am finding that std:multimap::equal_range returns incorrect results sometimes. Is this possible? If so, is there a workaround or some error in my code or hash function for pointers. Thank you.

Here is an excerpt of my code:

typedef std::multimap<char *,Range>::const_iterator I;
std::pair<I,I> b = mmultimap.equal_range(TmpPrevMapPtr);
for (I i=b.first; i != b.second; ++i){
    ranges_type.erase(i->second);
}
erasecount = mmultimap.erase(TmpPrevMapPtr);

where mmultimap has a hashed pointer key and a Range value. The class Range looks like this:

class Range { 
public:   
    explicit Range(int item){// [item,item] 
      mLow = item;
      mHigh = item;
      mPtr  = 0;
      mMapPtr = 0;
      mStamp = 0;
    }

    Range(int low, int high, char* ptr = 0,char* mapptr, int stamp){  
      mLow = low;
      mHigh = high;
      mPtr  = ptr;
      mMapPtr = mapptr;
      mStamp = stamp;
    }        

    int low() const { return mLow; }   
    int high() const { return mHigh; }
    char* getPtr() const { return mPtr; }
    char* getMapPtr() const { return mMapPtr; }
    int getStamp() const { return mStamp; }

private:   
    int mLow;   
    int mHigh; 
    char* mPtr;
    char* mMapPtr;
    int mStamp;
}; // class Range 

回答1:


You are comparing char* pointers for equality, when you want to compare C strings. You need to supply a comparison functor to multimap or (better yet) use std::string. Consider the following program and note how A1 != A2, but strcmp(A1, A2)==0.

#include <map>
#include <string>
#include <cstring>
#include <iostream>

struct compare {
 bool operator()(char *left, char *right) const {
  return std::strcmp(left,right) < 0;
 }
};


int main() {
  char A1[] = "A";
  char A2[] = "A";

  std::multimap<char*, int> bad;
  bad.insert(std::pair<char*,int>(A1, 1));
  bad.insert(std::pair<char*,int>(A2, 1));
  std::cout << bad.count("A") << ", " << bad.count(A1) << "\n";

  std::multimap<char*, int, compare> good;
  good.insert(std::pair<char*,int>(A1, 1));
  good.insert(std::pair<char*,int>(A2, 1));
  std::cout << good.count("A") << ", " << good.count(A1) << "\n";

  std::multimap<std::string, int> better;
  better.insert(std::pair<std::string,int>(A1, 1));
  better.insert(std::pair<std::string,int>(A2, 1));
  std::cout << better.count("A") << ", " << better.count(A1) << "\n";
}



回答2:


The way you are using the iterators is wrong. When using the erase method, the iterator became invalid. It must be reassigned with the erase method returned value.

In other words:

for (I i=b.first; i != b.second; ++i){
   ranges_type.erase(i->second);
}

should be

I i = b.first; 
while (i != b.second){
   i = ranges_type.erase(i->second);
}


来源:https://stackoverflow.com/questions/5982760/is-it-possible-for-stdmultimapequal-range-to-return-incorrect-results

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!