4

I have created a hash map and an iterator using the below lines:

std::map<const char*,vaLueClass *> myCache;
std::map<const char*,vaLueClass *>::iterator myCacheIterator;

Then I insert into this map using the below line:

myCache[anotherObject->getStringKey()] = new vaLueClass(anotherObj1->getIntAttr(), anotherObj1-->getIntAttr());

Then whenever I tried to search if an ENTRY for a particular string exist in this map or nut using below lines, it always enters the IF block which in other words it does not find any entries inside this map.

myCacheIterator= myCache.find(sampleObject->getstringKey());

NOTE: here sampleObject->getstringKey() returns the same key which has been inserted earlier.

if (myCacheIterator.operator ==(myCache.end())){
   // this block means that no matched entry is found inside the map myCache
}

Also, is this the proper way to create and use std::map in C++ ? If not then please suggest one.

Also, I have not used the keyword new to create the std::map object.

halfer
  • 18,701
  • 13
  • 79
  • 158
user3243499
  • 2,411
  • 5
  • 23
  • 44
  • 2
    Are you trying to compare the string data or the address the pointers hold? – NathanOliver Mar 01 '16 at 18:31
  • I want to check if an entry exist in this map with a particular (const char *) key – user3243499 Mar 01 '16 at 18:36
  • @user3243499 If you want to use strings and keys, use strings as keys, not `const char *`. In other words, use `std::string` as key values. – PaulMcKenzie Mar 01 '16 at 18:39
  • ok, if I use `std::string` instead of `const char *` then please suggest a sample replacement of my IF(condition) statement in order to check if a particular string key exist or not in my hash map – user3243499 Mar 01 '16 at 18:43
  • 2
    @user3243499 Why do you think you need to change anything? The `map::find` works correctly if what you're returning is a pointer to a (null-terminated) character sequence. – PaulMcKenzie Mar 01 '16 at 18:45
  • (Aside: please do not use the `>` quote formatting device as a general highlighter. This is widely understood to mean something that someone/something else said e.g. a paragraph quoted from a manual, an error quoted from the screen, etc. Thus it is confusing for readers who will wonder where it is a quote from). – halfer Mar 06 '16 at 12:54

2 Answers2

11

In a std::map, the keys are compared using the less-than operator < when performing a search. Since you're storing const char*'s as keys, this means that the lookups will compare the pointers themselves rather than the strings they point to, so if you don't pass in the exact pointer used to insert into the map, the lookup won't find anything.

I think the easiest fix here is to use std::strings as your keys, since the < operator on std::string actually compares the underlying text. That should fix your problem pretty quickly.

NathanOliver
  • 150,499
  • 26
  • 240
  • 331
templatetypedef
  • 328,018
  • 92
  • 813
  • 992
  • In this line `myCache[anotherObject->getStringKey()] = new vaLueClass(anotherObj1->getIntAttr(), anotherObj1-->getIntAttr());` the `anotherObject->getStringKey()` actually returns a `const char *` and I use this to insert in this map. So when I use the find method I might be using a different `const char *` pointer but have the same string. What should I do to achieve this ? – user3243499 Mar 01 '16 at 18:40
  • 1
    As suggested, use a `std::string` and not `const char *`. Problem solved. Also, you could have the same character sequence pointed to by different `const char *` values. Nothing stops the compiler from giving the string-literal "xyz" a different address than "xyz" found somewhere else in your program. – PaulMcKenzie Mar 01 '16 at 18:41
  • 1
    It worked perfectly after changing it from `const char *` to `std::string`. Got my concepts cleared. Thanks. – user3243499 Mar 01 '16 at 18:57
0

You can have several options to fix that:

1) You can use std::string instead of const char *

template<
    class Key,
    class T,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class map;

2) Map declaration can be seen above. Third template parameter is compare functor. You can pass your map a custom functor to implement the right behavior.

3) std::less uses operator< . You can write operator< for const char * .

mustafagonul
  • 1,017
  • 1
  • 13
  • 32