2011-05-12 50 views
1

下午好,我发现std:multimap::equal_range有时会返回不正确的结果。这可能吗?如果是这样,我的代码或指针的散列函数是否有解决方法或一些错误。谢谢。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有一个哈希指针键和一个范围值。类范围如下:

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 
+3

你是什么'的char *'键?它是一个指向C字符串或别的东西的指针吗?你真的想在这里使用指针吗? (也就是说,你真的想通过字符串的特定实例的地址来标识元素吗?)你确定你不想使用'std :: string'或其他字符串类吗? – 2011-05-12 18:41:06

+0

@詹姆斯麦克奈利斯,谢谢你的回复,你是正确的,char *键是一个指向C字符串的指针。理想情况下,我想使用一个指向C字符串的指针。我记得5年前参加了一个计算机科学课,Roni Khartoun教授给了我们一个任务,我们必须用指向C字符串的键构建哈希映射,我没有使用STL来解决这个问题。你是说在STL中最好不要使用char *指针作为std :: multimap的关键字吗?谢谢。 – Frank 2011-05-12 18:53:44

+0

只要你正确使用它们,你可以使用'char *'作为'std :: multimap'的键。只要认识到比较运算符(特别是'<和'std :: less')显示它们是否指向相同的字符串,而不是指向具有相同内容的字符串。 – 2011-05-12 19:02:02

回答

2

您比较char*指针平等,当你想要比较C字符串。你需要提供一个比较函数给multimap或(更好的)使用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"; 
} 
+0

谢谢你的回复。我在摘录中留下了一行代码:UnmapViewOfFile(PrevMapPtr); TmpPrevMapPtr = PrevMapPtr; typedef std :: multimap :: const_iterator I; std :: pair b = mmultimap.equal_range(TmpPrevMapPtr); for(I i = b.first; i!= b.second; ++ i){ranges_type.erase(i-> second); } erasecount = mmultimap.erase(TmpPrevMapPtr); – Frank 2011-05-12 19:11:21

+0

谢谢你的回复。我在摘录中留下了一行代码:1. UnmapViewOfFile(PrevMapPtr); 2. TmpPrevMapPtr = PrevMapPtr; 3。 typedef std :: multimap :: const_iterator I; 4. std :: pair b = mmultimap.equal_range(TmpPrevMapPtr); 5. for(I i = b.first; i!= b.second; ++ i){ranges_type.erase(i-> second); } 6. erasecount = mmultimap.erase(TmpPrevMapPtr);由于UnMapOfViewOfFile使char *指针无效,因此我们不能使用strcmp我们应该怎么做?谢谢。 – Frank 2011-05-12 19:25:29

+0

我不确定你在说什么,我不知道'UnmapViewOfFile'的作用,但我可以这样说:这些键在地图存在期间必须有效。最好的解决方法:使用'std :: string'作为键类型。 – 2011-05-12 19:31:19

1

您使用迭代器的方式是错误的。当使用擦除方法时,迭代器变得无效。必须重新分配擦除方法返回值。

换句话说:

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