C++ STL's MAP Container

J

Jazzkt

I wrote a little code using the map container available in the STL of C++.
The trouble I am having is that the find() member function is working
properly. When I try to find a key, if that key is not in the map, it
should return the iterator set to the address of the end of the map.

However, when I try to find a key in the map, it returns a value that is not
equal to the end of the map. I know beforehand that it will not find the
key and I expect the find() member function to return a pointer to the end
of the map.

The data is listed after the code sample below.

The code counts the occurrences of a string in a file. It stores the string
as the key in the map and the number of occurrences as the associated value.

Please help me find the error; I have included the code below:

map<char*, int> mp;

typedef pair<char*, int> pr;

map<char*, int>::iterator it;

...

/* put the string in the map */

if (mp.empty()) {

cnt = 1;

mp.insert(pr(ipStr,cnt));

}

else {

it = mp.find(ipStr);

if (it == mp.end()) { *** This is where it jumps to the 'else' ***

// add the new ip string

cnt = 1;

mp.insert(pr(ipStr,cnt));

}

else {

// increment the count

cnt = it->second;

cnt += 1;

it->second = cnt;

}

}

<><><>

Data:

218.190.48.173:4907

65.93.204.93:4989
 
C

Carl Daniel [VC++ MVP]

Jazzkt said:
I wrote a little code using the map container available in the STL of
C++. The trouble I am having is that the find() member function is
working properly. When I try to find a key, if that key is not in
the map, it should return the iterator set to the address of the end
of the map.

However, when I try to find a key in the map, it returns a value that
is not equal to the end of the map. I know beforehand that it will
not find the key and I expect the find() member function to return a
pointer to the end of the map.

The data is listed after the code sample below.

The code counts the occurrences of a string in a file. It stores the
string as the key in the map and the number of occurrences as the
associated value.

Please help me find the error; I have included the code below:

You haven't really included enough code to come to any conclusions, but I'm
suspicious of your use of char* was the key type.

When you use char* as the key type, the map will be comparing pointer values
to determine if two strings are equal. The map will not manage the strings
referenced by those pointers, neither copying them when you insert into the
map nor deleting them when you remove items from the map.

If you're inserting values from a local variable, it's entirely possible
that every pair you attempt to insert into the map has the same key value.

use std::map<std::string, int> instead.

-cd
 
D

Doug Harrison [MVP]

Jazzkt said:
I wrote a little code using the map container available in the STL of C++.
The trouble I am having is that the find() member function is working
properly. When I try to find a key, if that key is not in the map, it
should return the iterator set to the address of the end of the map.

However, when I try to find a key in the map, it returns a value that is not
equal to the end of the map. I know beforehand that it will not find the
key and I expect the find() member function to return a pointer to the end
of the map.

The data is listed after the code sample below.

The code counts the occurrences of a string in a file. It stores the string
as the key in the map and the number of occurrences as the associated value.

Please help me find the error; I have included the code below:

map<char*, int> mp;

typedef pair<char*, int> pr;

The pr typedef is better expressed with map<char*, int>::value_type.
Actually, you should make a typedef for your map, too.

The problem is twofold. First, map<char*, int> uses less<char*> and thus
compares pointers, not the strings they point to. Second, it sounds like
you're trying to find the same char* you've inserted into the map, perhaps
because you're using the address of a local buffer. It's impossible to be
sure from the code fragments you posted. Whatever the reason, you can fix
the problem by storing std::string instead of char*.
map<char*, int>::iterator it;

...

/* put the string in the map */

if (mp.empty()) {

cnt = 1;

mp.insert(pr(ipStr,cnt));

}

else {

it = mp.find(ipStr);

if (it == mp.end()) { *** This is where it jumps to the 'else' ***

// add the new ip string

cnt = 1;

mp.insert(pr(ipStr,cnt));

}

else {

// increment the count

cnt = it->second;

cnt += 1;

it->second = cnt;

}

}

I don't want to give away too much, but see if you can replace all the above
with a single line of code no more than a dozen or so characters long.
 
C

Carl Daniel [VC++ MVP]

Doug said:
I don't want to give away too much, but see if you can replace all
the above with a single line of code no more than a dozen or so
characters long.

Life IS a test, afterall ;-)

-cd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top