STL map and char * problems

Discussion in 'C++' started by Digital Puer, Aug 19, 2009.

  1. Digital Puer

    Digital Puer Guest

    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.
    Digital Puer, Aug 19, 2009
    #1
    1. Advertising

  2. Digital Puer

    peter koch Guest

    On 19 Aug., 23:57, 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>
    > 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
    peter koch, Aug 19, 2009
    #2
    1. Advertising

  3. Digital Puer

    SG Guest

    On 19 Aug., 23:57, 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>
    > 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
    SG, Aug 19, 2009
    #3
  4. 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
    Marcel Müller, Aug 19, 2009
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marcus
    Replies:
    2
    Views:
    577
    Marcus
    Dec 9, 2005
  2. Replies:
    2
    Views:
    539
    klaus hoffmann
    Feb 22, 2006
  3. kl
    Replies:
    7
    Views:
    1,270
    James Kanze
    Jan 1, 2008
  4. Replies:
    1
    Views:
    404
    red floyd
    Dec 21, 2008
  5. Luca Risolia

    STL map to STL vector

    Luca Risolia, Jan 13, 2014, in forum: C++
    Replies:
    32
    Views:
    331
    Seungbeom Kim
    Jan 18, 2014
Loading...

Share This Page