Sign in to follow this  
blaze02

stdext::hash_map

Recommended Posts

blaze02    100
You can skip all this if you don't care about my code :) I'm using hash_map to convert (const char *)'s into unsigned ints that index positions in a vector. So I've got a bunch of filenames, some of which can be duplicates, different cases, or prefixed with slashes, whatever. Given a unique filename, it hashes to an index into a vector (a non-unique index; 2 files can point to the same spot in the vector). For now, I'm #define'ing all my filenames so they are all different. The way the code works is: 1) Call GetIndex(std::string filename) to get the index. This will load the texture in a seperate thread if necessary. 2) Call GetTexture(unsigned int index) to get the texture pointer. This will usually return NULL the first call because the texture is not loaded yet. PROBLEM: So my problem is pretty weird. I have a stdext::hash_map<const char*, unsigned int> STRING2UINT; STRING2UINT StringToIndex; Key type is a const char *, but I'm using std::string so I .c_str() every time I want to index the hash_map. I call StringToIndex[filename.c_str()] = index; to add an filename / index association. I add an association on only one line of my code. I call iter = StringToIndex.find(filename.c_str()); to get an iterator and iter->first && iter->second are the key = const char * && type = unsigned int index. My code adds 4 files without a problem. All of them look something like ART//<filename>.png Then when it goes to load the 5th file, the find method returns an iterator with ->first exactly the same as my 5th file, but ->second is the index to the 1st file. Also, I've changed my code to have a dummy node at the front of the vector, so index = 0 should never happen. And it doesn't, the iterator->second is now 1, which is the first texture. The code is fairly small (350 lines). So the problem is I only add an association into the hash_map at one spot. Then, an association is found that is wrong and I didn't add it. Any ideas?

Share this post


Link to post
Share on other sites
Oluseyi    2111
First, did you verify correct construction and population of the stdext::hash_map?

The indices in a std::map or stdext::hash_map are compared using std::less, which, for const char *, is operator<. Two "identical" strings referred to by different pointers will be recognized as different values. Use std::string for your key type.

Share this post


Link to post
Share on other sites
Conner McCloud    1135
Quote:
Original post by Oluseyi
First, did you verify correct construction and population of the stdext::hash_map?

The indices in a std::map or stdext::hash_map are compared using std::less, which, for const char *, is operator<. Two "identical" strings referred to by different pointers will be recognized as different values. Use std::string for your key type.

That was my first thought as well, that the default hash [which won't be std::less, by the way] wouldn't know to deal with pointers. However, SGIs page says that their implementation is specialized for const char* keys, which I would assume means that it isn't doing a naive pointer comparison. That might still be the problem, of course, since he probably isn't using SGIs implementation.

Personally, I've never used hash_map, so I'm not much help.

CM

Share this post


Link to post
Share on other sites
blaze02    100
How would I go about verifying correct construction and population? Most of all my debug'ing values can't read into a hash_map. Like I said, it works fine for the first 4 filenames.

I was using (const char *) because I figured it was a specialized template.

Well... it turns out it works with std::string. I'm not entirely sure where the problem was, I'll let you know if I figure out.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this