Map not inserting

Hi Guys,

I am having a really weird problem, I am trying to insert a value in the map and for some reason in one part of the code it is working and not working for another part of the code. Here is the code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
int  main() {
map<char*,char*>M;
ifstream readFile;
readFile.open("textfile.txt");

if (readFile.is_open()) {
    char *p;
    string str;
char buf[100];  
    while (!readFile.eof()) {
      getline(readFile,str); 
strcpy(buf, str.c_str());
char a[10]; 
char b[16]; 


memset(a,NULL,10);
memset(b,NULL,16); 

      p = strtok(buf," \t"); 
while(p != NULL) {
strcpy(a,p);
p = strtok(NULL, " \t");
strcpy(b,p);
 M.insert(pair<char*,char*>(a,b)); //does not work 

p = strtok(NULL, " \t");
}


    }

}
cout<<"--------------"<<endl;

char a[10] ;
char b[10] ;
char *p1 = "Hello";
char *p2 = "World";
strcpy(a,p1);
strcpy(b,p2);
M.insert(pair<char*,char*>(a,b)); //Does Work 
map<char*,char*>::iterator it;
for (it = M.begin(); it!=M.end();it++){
   cout<<(*it).first<<"     "<<(*it).second<<endl;
}

return 0;
}


Any suggestions?

Thanks
You probably shouldn't store char* in a map like this. Reason being is that char* is a pointer and not a string. So when you add a and b like this, you're adding a pointer to the map -- a pointer which goes bad when that buffer loses scope and is destroyed. This could be causing some problems in your program.

I suspect insert is failing because the key is a pointer... or the pointers are bad by the time you're checking the map. Example:

1
2
3
4
5
6
7
8
9
10
char a[10];
char b[16];

strcpy(a,"foo");
strcpy(b,"test");

M.insert(pair<char*,char*>(a,b));  // inserts pointer to 'a' as key

strcpy(a,"bar");
M.insert(pair<char*,char*>(a,b));  // fails because 'a' already exists as key 


You might be expecting this to make two entries in the map... one with a "foo" key, and another with a "bar" key, but that's not what happens. Because you're using a char* for a key, it's storing the pointer to the string buffer, rather than the string data itself (and of course, the pointer doesn't change no matter what the string contains).

The solution here is to use std::string instead of char*.
With a char* as the key, the map is sorting the elements by their pointer value, not by the string the pointers refer to.
Thanks @Disch and @jsmith. You guys are absolutely right. I figured this out last night, it was really annoying. But just of curiosity, is there any way by which we can have char* as key?
or it's just we cannot ever use it as key?

Thanks
basically, no. I mean technically you can but it would behave like it was behaving before (acting like an integer key).

char* does not store the actual string information, it just points to it. For the actual string information, you'd need a char array, and you can't use arrays with map (or any other standard container type) unless you objectify them inside of a class (which is basically all std::string does)
You have to write your own comparator then. map's 3rd template parameter is a comparator function.

1
2
3
4
5
bool my_str_less_than( const char* s1, const char* s2 ) {
   return strcmp( s1, s2 ) < 0;
}

map<char*, char*, my_str_less_than> my_map;

Thanks a lot guys !
Topic archived. No new replies allowed.