querry related to STL map..

R

ravips

I have a map<char *,int> it does not work consistently. I have used
similar sort of implementation as below:

map<char *,int> m1;
map<char *,int>::iterator i;

m1["January"] = 31;
m1["February"] = 28;
m1["March"] = 31;
m1["April"] = 30;
m1["May"] = 31;
m1["June"] = 30;
m1["July"] = 31;

This is similar to the map that i have used. Now accessing this yields
different results as below:

Option1:

char *p = "May";
int it = m1[p]; // Works properly returns 31.

Option2:
char *p = new char[3];
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

Can anybody help me to resolve this issue?

Thanks.
 
K

Kai-Uwe Bux

ravips said:
I have a map<char *,int> it does not work consistently. I have used
similar sort of implementation as below:

map<char *,int> m1;
map<char *,int>::iterator i;

m1["January"] = 31;
m1["February"] = 28;
m1["March"] = 31;
m1["April"] = 30;
m1["May"] = 31;
m1["June"] = 30;
m1["July"] = 31;

This is similar to the map that i have used. Now accessing this yields
different results as below:

Option1:

char *p = "May";
int it = m1[p]; // Works properly returns 31.

Option2:
char *p = new char[3];
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

Can anybody help me to resolve this issue?

Use map< string, int > instead: when using char* the map will store a the
address of the first character and use that address for comparison. It will
not compare the actual C-strings. That is, if you use a different address
pointing to a C-string that happens to read alike some stored in the map,
the map entry will not be found. In that case, the map allocates a new
entry and initialized the value with the default int (i.e., 0). This is
what you observed.


Best

Kai-Uwe Bux
 
A

Andrew Koenig

ravips said:
I have a map<char *,int> it does not work consistently.

Don't use char* as a key type; it is very unlikely to work as you expect.
Use std::string instead.
 
R

Rolf Magnus

ravips said:
I have a map<char *,int> it does not work consistently. I have used
similar sort of implementation as below:

map<char *,int> m1;
map<char *,int>::iterator i;

You should prefer std::string over pointers to char.
m1["January"] = 31;
m1["February"] = 28;
m1["March"] = 31;
m1["April"] = 30;
m1["May"] = 31;
m1["June"] = 30;
m1["July"] = 31;

This is similar to the map that i have used. Now accessing this yields
different results as below:

Option1:

char *p = "May";
int it = m1[p]; // Works properly returns 31.

Then you got very bad luck. Your compiler probably found out that the
literal "May" is there several times and added it to the program only once.
Option2:
char *p = new char[3];
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

Can anybody help me to resolve this issue?

Remember that std::map keeps its items sorted by key. For that, it comares
key values. It also uses such a comparison to find specific items. In your
case, the key type is a pointer, so you get a pointer comparison, and
nothing more.
You either need to use a string class like std::string, which will do a real
string comparison, or you have to write your own comparison function that
the map can use.
 
T

Thomas Tutone

ravips said:
I have a map<char *,int> it does not work consistently. I have used
similar sort of implementation as below:

map<char *,int> m1;
map<char *,int>::iterator i;

m1["January"] = 31;
m1["February"] = 28;
m1["March"] = 31;
m1["April"] = 30;
m1["May"] = 31;
m1["June"] = 30;
m1["July"] = 31;

This is similar to the map that i have used. Now accessing this yields
different results as below:

Option1:

char *p = "May";
int it = m1[p]; // Works properly returns 31.

Option2:
char *p = new char[3];
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

Can anybody help me to resolve this issue?

You have two choices.

Make it a std::map<std::string, int> instead of a std::map<char*, int>.
Then it will work fine. That is the preferred solution.

If you insist on using char* instead (why?), then do the following:

struct ltstr
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};

and then make it a std::map<const char*, int, ltstr> instead of a
std::map<char*, int>. That way you are providing a functor to do the
proper comparison between char*.

Best regards,

Tom
 
M

Martin Steen

ravips said:
Option2:
char *p = new char[3];

Buffer overflow? "May" needs 4 chars (zero terminated string!)
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

Can anybody help me to resolve this issue?

- Martin
 
D

Daniel T.

"ravips said:
I have a map<char *,int> it does not work consistently. I have used
similar sort of implementation as below:

map<char *,int> m1;
map<char *,int>::iterator i;

m1["January"] = 31;
m1["February"] = 28;
m1["March"] = 31;
m1["April"] = 30;
m1["May"] = 31;
m1["June"] = 30;
m1["July"] = 31;

This is similar to the map that i have used. Now accessing this yields
different results as below:

Option1:

char *p = "May";
int it = m1[p]; // Works properly returns 31.

Option2:
char *p = new char[3];
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

Can anybody help me to resolve this issue?

You can resolve this in one of two ways. Best would be to have the map
hold the string by value instead of pointer...

map<string, int> m1;

Second up would be to create a comparison function for char*s:

bool leftBeforeRight( const char* lhs, const char* rhs ) {
return strcmp( lhs, rhs ) < 0;
}

map<char*, int,
pointer_to_binary_function<const char*, const char*, bool> >
m1( ptr_fun( &leftBeforeRight ) );
 
D

dayton

Option2:
char *p = new char[3];
strcpy(p, "May");
int it = m1[p]; // returns 0 .. instead of 31 ....

"May" has a trailing '\0'. strcpy() copies that trailing '\0',
but you've only allocated space for 3 characters.

/Glen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,156
Latest member
KetoBurnSupplement
Top