multimap on C-style string key не может вставить записи

Я пытаюсь создать мультикарту, проиндексированную на строку в стиле 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, разделенные пробелом), вместо того, чтобы показывать мне каждое значение для каждого используемого значения ключа.

Куда я в этом ошибаюсь?

Спасибо

2

Решение

strcmp неверный предикат для использования в multimap,
Предикат должен удовлетворять следующему:

Выражение comp (a, b), где comp является объектом этого класса сравнения, а a и b являются ключевыми значениями, должно возвращать true, если a нужно поместить в более раннюю позицию, чем b, в операции строгого слабого упорядочения.

strcmp нарушает это, потому что он возвращает ненулевое значение, если строки неравны, либо < б или а> б.

Вы должны определить свой собственный предикат, который возвращает true если и только если первая строка меньше второй.

4

Другие решения

    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) эти указатели указывают на то, когда они выходят из области видимости. Это оставляет контейнер, содержащий информацию, которая теперь не имеет смысла.

3

Вы используете память о key а также value долго после того, как они выходят за рамки. На самом деле, все ваши char* указатели указывают на один и тот же фрагмент стековой памяти, и этот фрагмент готов к повторному использованию к тому времени, когда вы на самом деле посмотрите на него.

Чтобы делать то, что вы хотите, вы должны использовать strdup() создать постоянную копию вашего char * данные. Конечно, тогда вам нужно побеспокоиться об освобождении его позже.

1
По вопросам рекламы [email protected]