multimap on C-style string key fails to insert entries

别等时光非礼了梦想. 提交于 2019-12-12 19:03:14

问题


I am trying to create a multimap indexed on a C-style string, as shown in the following code segment:

    #include <cstring>
    #include <map>
    #include <iostream>

    using namespace std;

    int main(void)
    {
        int i, j;
        int (*fn_pt)(const char *, const char *) = strcmp;
        multimap<char *, char *, int (*)(const char *, const char *)>a(fn_pt);

        for (i = 0; i < 2; i++)
        {
            char key[2];
            sprintf(key, "%d", i);
            for (j = 0; j< 5; j++)
            {
                char value[2];
                sprintf(value, "%d", j);
                a.insert(pair<char *, char *>(key, value));
            }
        }

        for (i = 0; i < 2; i++)
        {
            char key[2];
            sprintf(key, "%d", i);
            multimap<char *, char *>::iterator it = a.find(key);
            while (it != a.end())
            {
                cout << it->first << "\t" << it->second <<endl;
                it++;
            }
        }
    }

Simply changing the key in the above program to integer gives me the expected result. But, indexing the multimap on a string is giving me something unexpected (only rows of 1's and 4's separated by space), instead of showing me every value for every key value used.

Where am I going wrong in this?

Thanks


回答1:


strcmp is a wrong predicate to use in multimap. The predicate shall satisfy the following:

The expression comp(a,b), where comp is an object of this comparison class and a and b are key values, shall return true if a is to be placed at an earlier position than b in a strict weak ordering operation.

strcmp violates that because it returns a nonzero value if the strings are unequal, either a < b or a > b.

You should define your own predicate which returns true if and only if the first string is less than the second.




回答2:


    multimap<char *, char *, int (*)(const char *, const char *)>a(fn_pt);

    for (i = 0; i < 2; i++)
    {
        char key[2];
        sprintf(key, "%d", i);
        for (j = 0; j< 5; j++)
        {
            char value[2];
            sprintf(value, "%d", j);
            a.insert(pair<char *, char *>(key, value));
        }
    }

You're storing two pointers in a container, and then you're destroying the objects (key and value) those pointers point to when they go out of scope. This leaves the container holding information that is now meaningless.




回答3:


You're using the memory of key and value long after they go out of scope. In fact, all your char* pointers point at the same piece of stack memory, and that piece is ready to be reused by the time you actually look at it.

To do what you want you need to use strdup() to create a permanent copy of your char * data. Of course, then you need to worry about deallocating it later.



来源:https://stackoverflow.com/questions/12689981/multimap-on-c-style-string-key-fails-to-insert-entries

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!