Reputation: 400
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
Upvotes: 2
Views: 576
Reputation: 8594
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.
Upvotes: 4
Reputation:
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.
Upvotes: 1
Reputation: 182753
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.
Upvotes: 3