开发者

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

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 开发者_如何学Cyou.

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 


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";
}


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);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜