2011-05-12 52 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); 
}