Возможно ли для std :: multimap :: equal_range возвращать неверные результаты? - PullRequest
1 голос
/ 12 мая 2011

Добрый день, я обнаружил, что std:multimap::equal_range иногда возвращает неверные результаты. Это возможно? Если так, есть ли обходной путь или какая-то ошибка в моем коде или хэш-функция для указателей. Спасибо.

Вот выдержка из моего кода:

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

, где mmultimap имеет хешированный указатель и значение Range. Класс Range выглядит так:

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 

Ответы [ 2 ]

2 голосов
/ 12 мая 2011

Вы сравниваете char* указатели на равенство, когда хотите сравнить строки C.Вам необходимо предоставить функтор сравнения для мультикарты или (еще лучше) использовать std :: string.Рассмотрим следующую программу и отметим, как A1! = A2, но 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";
}
1 голос
/ 15 февраля 2012

То, как вы используете итераторы, неверно.При использовании метода стирания итератор становится недействительным.Он должен быть переназначен возвращаемым значением метода стирания.

Другими словами:

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

должно быть

I i = b.first; 
while (i != b.second){
   i = ranges_type.erase(i->second);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...