2011-05-13 97 views
3

我想寫一個管理包含指針,其中鍵是一個字符串的STL地圖的對象的副本構造函數。然而,當我試圖在地圖中插入新的值時,指針設置爲NULL:C + + STL映射與自定義比較存儲空指針

// ... 
for(std::map<std::string, data_base*, order>::const_iterator it = other.elements.begin(); 
it != other.elements.end(); ++it){ 
    data_base *t = it->second->clone(); 
    std::cout << "CLONE: " << std::hex << t << std::endl; 
    elements[it->first] = t; 
    std::cout << "INSERTED: " << std::hex << elements[it->first] << std::endl; 
} 
// ... 

other是被複制和elements地圖的對象。 clone()方法返回一個指向新對象的指針(通過new)。

運行上面的代碼,我得到的是這樣的:

CLONE: 0xcfbbc0 
INSERTED: 0 

我不是一個非常有經驗的程序員,這個問題可能是簡單修復,但我沒有找到任何解決方案,它周圍搜索。

非常感謝您的時間。

回答

4

我看不出有任何問題與此代碼,除了也許

std::map<std::string, data_base*, order>::const_iterator it 

這裏order給出了關鍵比較使用包含在地圖上(通常作爲一棵樹)的對進行排序。

也許你做錯了什麼,使你的[]運算符找不到合適的ke,使你的最後一行記錄一個新的ptr對。

首先,嘗試沒有order,使用默認鍵比較(std :: less),然後如果它不起作用,請發佈您的order定義和地圖聲明。如果這還不夠,只需提供一個簡單的完整程序來重現問題。


我只是寫了一個簡單的類似的測試,使用默認鍵比較:

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

struct Data 
{ 
    int k; 

    Data* clone() { return new Data(); } 
}; 

typedef std::map< std::string, Data* > DataMap; 

DataMap data_map; 


int main() 
{ 
    data_map[ "hello" ] = new Data(); 
    data_map[ "world" ] = new Data(); 

    DataMap other_map; 

    for(DataMap::const_iterator it = data_map.begin(); it != data_map.end(); ++it) 
    { 
      Data*t = it->second->clone(); 
      std::cout << "CLONE: " << std::hex << t << std::endl; 
      other_map[it->first] = t; 
      std::cout << "INSERTED: " << std::hex << other_map[it->first] << std::endl; 
    } 

    std::cin.ignore(); 

    return 0; 
} 

在VS2010SP1,此輸出:

CLONE: 00034DD0 
INSERTED: 00034DD0 
CLONE: 00035098 
INSERTED: 00035098 

所以它應該是問題,或者也許你之前做錯了什麼。

+0

'訂單'函數對象確實是不正確的,註釋它使地圖行爲正確。謝謝。 – newbie 2011-05-13 23:11:03

+1

這一個不容易,我很驚訝,我發現它。 :) – Klaim 2011-05-13 23:11:57

0

試試這個,以幫助調試問題。我建議仔細檢查order函數是否正確。您可以將其刪除以使用std::less<T>,這是已知的工作。

// ... 
typedef std::map<std::string, data_base*, order> string_db_map; 
for(string_db_map::const_iterator it = other.elements.begin(); 
    it != other.elements.end(); 
    ++it) 
{ 
    data_base *t = it->second->clone(); 
    std::cout << "CLONE: " << std::hex << t << std::endl; 
    std::pair<string_db_map::iterator, bool) result = elements.insert(
     string_db_map::value_type(it->first, t)); 
    if (!result.second) 
    { 
     std::cout << "element['" << it->first << "'] was already present, and replaced." << std::endl; 
    } 
    std::coud << "INSERTED [iterator]: " << std::hex << (*result.first).second << std::endl; 
    std::cout << "INSERTED [indexed]: " << std::hex << elements[it->first] << std::endl; 
} 
// ...