2011-05-13 99 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; 
} 
// ...