2

我正在尝试创建一个以 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 的行由空格分隔),而不是向我显示使用的每个键值的每个值。

我在哪里错了?

谢谢

4

3 回答 3

4

strcmp是在 中使用的错误谓词multimap。谓词应满足以下条件:

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

strcmp违反了这一点,因为如果字符串不相等(a < b 或 a > b),它会返回一个非零值。

您应该定义自己的谓词,true 当且仅当第一个字符串小于第二个字符串时才返回。

于 2012-10-02T12:17:26.680 回答
3
    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));
        }
    }

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

于 2012-10-02T12:17:42.660 回答
1

您正在使用它们的内存key并且value在它们超出范围之后很久。事实上,你所有的char*指针都指向同一块堆栈内存,而当你真正看到它时,那块内存已经准备好被重用了。

要做你想做的事,你需要用它strdup()来创建数据的永久副本char *。当然,那么您需要担心以后释放它。

于 2012-10-02T12:19:05.830 回答