Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > STL map and char * problems

Reply
Thread Tools

STL map and char * problems

 
 
Digital Puer
Guest
Posts: n/a
 
      08-19-2009
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.
 
Reply With Quote
 
 
 
 
peter koch
Guest
Posts: n/a
 
      08-19-2009
On 19 Aug., 23:57, Digital Puer <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
 
 
 
SG
Guest
Posts: n/a
 
      08-19-2009
On 19 Aug., 23:57, Digital Puer <(E-Mail Removed)> wrote:
> 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
 
Reply With Quote
 
Marcel Müller
Guest
Posts: n/a
 
      08-19-2009
Digital Puer wrote:
> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
STL map or hash map using struct as data and find it kl C++ 7 01-01-2008 11:05 AM
(const char *cp) and (char *p) are consistent type, (const char **cpp) and (char **pp) are not consistent lovecreatesbeauty C Programming 1 05-09-2006 08:01 AM
a stl map which use stl pair as the key Allerdyce.John@gmail.com C++ 2 02-22-2006 07:25 AM
STL: Map of maps possible, but no multi-map of maps? Workarounds? Marcus C++ 2 12-09-2005 06:34 AM
char* and STL map Bart Kevelham C++ 3 10-07-2003 04:30 AM



Advertisments