C 样式字符串键上的多重映射无法插入条目

multimap on C-style string key fails to insert entries

本文关键字:映射 插入 字符串 样式      更新时间:2023-10-16

我正在尝试创建一个在 C 样式字符串上索引的多重映射,如以下代码段所示:

    #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++;
            }
        }
    }

只需将上述程序中的键更改为整数即可获得预期的结果。但是,在字符串上索引多重映射会给我一些意想不到的东西(只有 1 和 4 的行用空格分隔),而不是向我显示使用的每个键值的每个值。

我哪里做错了?

谢谢

strcmpmultimap中使用是一个错误的谓词。谓词应满足以下条件:

表达式 comp(a,b),其中 comp 是此比较类的对象,a 和 b 是键值,如果要在严格的弱排序操作中将 a 放置在比 b 更早的位置,则应返回 true。

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));
        }
    }

您将两个指针存储在一个容器中,然后销毁这些指针在超出范围时指向的对象(keyvalue)。这使得容器中保存的信息现在毫无意义。

您正在使用key的内存,并且在它们超出范围很久之后value。事实上,你所有的char*指针都指向同一个堆栈内存,当你实际查看它时,该片段已经准备好重用。

要执行所需的操作,您需要使用 strdup() 来创建char *数据的永久副本。当然,然后您需要担心稍后会解除分配它。