【问题标题】:C++ STL map with custom comparator storing null pointers具有存储空指针的自定义比较器的 C++ STL 映射
【发布时间】:2011-05-14 07:11:38
【问题描述】:

我正在尝试为管理包含指针的 STL 映射的对象编写复制构造函数,其中键是字符串。但是,当我尝试在地图中插入新值时,指针被设置为 NULL:

// ...
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

我不是一个很有经验的程序员,这个问题可能很容易解决,但我没有找到任何解决方案。

非常感谢您的宝贵时间。

【问题讨论】:

    标签: c++


    【解决方案1】:

    我认为这段代码没有任何问题,除了可能

    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
    

    所以这应该是问题所在,或者你之前做错了什么。

    【讨论】:

    • order 函数对象确实不正确,将其注释掉会使地图正常运行。谢谢。
    • 这并不容易,我很惊讶我找到了它。 :)
    【解决方案2】:

    试试这个,以帮助调试问题。我建议仔细检查 order 函数是否正确。您可以删除它以使用已知有效的std::less&lt;T&gt;

    // ...
    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;
    }
    // ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-07
      • 2017-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多