开发者

C++ STL map with custom comparator storing null pointers

开发者 https://www.devze.com 2023-03-06 01:07 出处:网络
I\'m trying to write a copy constructor for an object managing a STL map containing pointers, where the key is a string. However, when I attempt to insert new values in the map, the pointers are set t

I'm trying to write a copy constructor for an object managing a STL map containing pointers, where the key is a string. However, when I attempt to insert new values in the map, the pointers are set to 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;
    elemen开发者_如何学JAVAts[it->first] = t;
    std::cout << "INSERTED: " << std::hex << elements[it->first] << std::endl;
}
// ...

other is the object being copied and elements the map. The clone() method returns a pointer to a new object (via new).

Running the code above I get something like:

CLONE: 0xcfbbc0
INSERTED: 0

I'm not a very experienced programmer and this issue is probably simple to fix, but I didnt find any solution to it searching around.

Thanks a lot for your time.


I don't see any problem with this code, other than maybe

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

Here order gives the key comparator to use to sort the pairs contained in the map (often implemented as a tree).

Maybe you're doing something wrong in it, making your [] operator don't find the right ke, making your last line logging a new pair with a null ptr.

First, try without that order, using the default key-comparator (std::less), then if it don't work, post your order definition and the map declaration. If it's not enough, just provide a simple complete program that reproduce the problem.


I just wrote a simple similar test, using the default key-comparator :

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

On VS2010SP1, this outputs :

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

So it should be the problem, or maybe you're doing something wrong before.


Try this out, to help debug the issue. I'd recommend double-checking that the order function is correct. You can remove it to use std::less<T>, which is known to work.

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

精彩评论

暂无评论...
验证码 换一张
取 消