STL map and char * problems

D

Digital Puer

I am having a problem with the STL map and char *.
I'm on Linux and am using g++ 4.1.2.

I am using two STL maps:

1. map<char *, int>
2. map<string, int>

For some reason, when I insert the same char strings and
then iterate over them, the map from (1) will not print the
keys in the expected lexical (alphabetical) order, but the
map from (2) will print the keys in order. I would prefer
to use map (1).

Here is a program that demonstrates this problem.



map<char *, int> keyCountsChar;
keyCountsChar["bbtman"] = 1;
keyCountsChar["batman"] = 1;
keyCountsChar["aorta"] = 1;
keyCountsChar["dude"] = 1;

printf("content of keyCountsChar:\n");
for (map<char *, int>::iterator iter = keyCountsChar.begin();
iter != keyCountsChar.end();
iter++)
{
printf("%s --> %d\n", iter->first, iter->second);
}

map<string, int> keyCountsString;
keyCountsString["bbtman"] = 1;
keyCountsString["batman"] = 1;
keyCountsString["aorta"] = 1;
keyCountsString["dude"] = 1;

printf("content of keyCountsString:\n");
for (map<string, int>::iterator iter = keyCountsString.begin();
iter != keyCountsString.end();
iter++)
{
printf("%s --> %d\n", iter->first.c_str(), iter->second);
}



The output is:

content of keyCountsChar:
bbtman --> 1
batman --> 1
aorta --> 1
dude --> 1

content of keyCountsString:
aorta --> 1
batman --> 1
bbtman --> 1
dude --> 1


As you can see, the map with the string iterates over the
keys in the correct lexical order, but the maps with the char *
does not.

Can someone please help me out? I would like to use
the map with the char * and still iterate in lexical order.
 
P

peter koch

I am having a problem with the STL map and char *.
I'm on Linux and am using g++ 4.1.2.

I am using two STL maps:

1. map<char *, int>
2. map<string, int>

For some reason, when I insert the same char strings and
then iterate over them, the map from (1) will not print the
keys in the expected lexical (alphabetical) order, but the
map from (2) will print the keys in order. I would prefer
to use map (1).
Why? That would have very limited use.
Can someone please help me out? I would like to use
the map with the char * and still iterate in lexical order.

You can add a comparing function in the map-type. For char* std::maps
default comparator is (of course!) a pointer-comparator.

/Peter
 
S

SG

I am having a problem with the STL map and char *.
I'm on Linux and am using g++ 4.1.2.

I am using two STL maps:

1. map<char *, int>
2. map<string, int>

For some reason, when I insert the same char strings and
then iterate over them, the map from (1) will not print the
keys in the expected lexical (alphabetical) order,

Of course not. Why should it? The less than operator for pointers just
compares the addresses.
  map<char *, int> keyCountsChar;
  keyCountsChar["bbtman"] = 1;
  keyCountsChar["batman"] = 1;
  keyCountsChar["aorta"] = 1;
  keyCountsChar["dude"] = 1;

Even without additional compiler switches you should have seen a big
fat warning here about conversions of string literals (const char[])
to pointers to non-const char.
I would like to use
the map with the char * and still iterate in lexical order.

Why not "char const*"? As for sorting: you can use your own comparator
objekt. Checkout the documentation of your standard library on how to
do that. Hint: std::map takes 4 template parameters. The 3rd one is
the type of the comparator which defaults to std::less<Key>.

Cheers!
SG
 
M

Marcel Müller

Digital said:
I am having a problem with the STL map and char *.
I'm on Linux and am using g++ 4.1.2.

I am using two STL maps:

1. map<char *, int>

1. You do not store strings in the map key here.
You store pointers to strings in the map key.

2. You ordered the entries by the pointers.
This obviously does not what you expect.
You could use a custom comparer, but it probably won't help.
(see below)

3. You have a very high risk of undefined behavior
because you can not easily control the storage
behind your char* pointers.
The pointers may point to temporaries on the stack
causing dangling references.
The storage they point to may change while the map exists.
The will change your keys by the back door.
So if you have a custom comparer it would most likely
violate the Strict Weak Ordering requirement in this case.

4. DO NOT USE char* IN C++ CODE.
It is almost always at least a risk.
Use const char* or std::string.

See example: http://www.sgi.com/tech/stl/Map.html
But this only works as long as your strings are located in static
constant storage.


Marcel
 

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

Similar Threads


Members online

Forum statistics

Threads
474,037
Messages
2,570,371
Members
47,013
Latest member
JewellChes

Latest Threads

Top