Reputation: 503
typedef std::vector<UCHAR> RESPONSE_BUFFER;
typedef TimedHashMap<int, RESPONSE_BUFFER*> TimeResponseHashMap;
Inner map prototype has "integer" as key and "pointer to a vector of chars" as mapped value.
TimeResponseHashMap* inner_pending_response_map;
Outer map is a map of maps. it has "integer" as key and "pointer to inner map" as mapped value.
std::map<int, TimeResponseHashMap* > outer_pending_response_map;
I insert like this: Inner map is a userdefined map, hence it has a different format.
inner_pending_response_map->Insert((int)s16MessageID, &resp_buffer, expirytime);
outer_pending_response_map.insert(make_pair((int)s16SessionID,
inner_pending_response_map));
TimeResponseHashMap provides the user defined interface "Find" to access members of the map.
template <typename Key, typename ElementObject>
THM_ERROR TimedHashMap<Key, ElementObject>::Find(const Key& k, ElementObject& e)
{
typename hash_map<Key, BaseElement_*, dw_hash<Key>, dw_equal_to<Key> >::iterator itr;
try
{
itr = h_->find(k);
} catch ( ... )
{
return E_INTERNAL_ERROR;
}
if ( itr == h_->end() )
{
e = NULL;
return E_ITEM_NOT_FOUND;
}
e = itr->second->e_;
return E_SUCCESS;
}
I have both the keys and now I need to access the "mapped value" of the inner map. The inner map uses the above Find() function to search. I need to pass RESPONSE_BUFFER variable as the second parameter to the Find() function.
I'm trying to extract like this which gives a wrong output:
RESPONSE_BUFFER resp_buffer;
ExtractFragmentResponse(u16Key1, u16Key2, &resp_buffer);
Definition of ExtractFragmentResponse is below:
STATUS
C_THREAD::ExtractFragmentResponse(USHORT u16SessionID, USHORT u16MessageID,
RESPONSE_BUFFER* resp)
{
(((outer_pending_response_map.find(u16SessionID))->second)->Find((int)u16MessageID, resp))
}
resp is not giving me correct data. How can it be done?
Upvotes: 0
Views: 519
Reputation: 35440
This may not directly answer the question, but it does bring up why the code used is highly faulty and should be broken up into several lines.
STATUS
C_THREAD::ExtractFragmentResponse(USHORT u16SessionID, USHORT u16MessageID,
RESPONSE_BUFFER* resp)
{
(((outer_pending_response_map.find(u16SessionID))->second)->Find((int)u16MessageID, resp))
}
Let's say this did actually "work". There is a major problem with it, regardless. The issue is this:
outer_pending_response_map.find(u16SessionID)
What happens if find
doesn't find the entry u16SessionID
? You now have been returned outer_pending_response_map.end()
. When this return value is used like this:
outer_pending_response_map.end()->second
boom, your dead. That line attempts to use an invalid iterator, which is undefined behavior.
What you should do is this:
std::map<int, TimeResponseHashMap* >::iterator it1 = outer_pending_response_map.find(u16SessionID);
if ( it1 != outer_pending_response_map.end())
(it1->second)->Find((int)u16MessageID, resp);
else
{
// you fill in what happens if the find fails
}
To debug your issue, you can then further break up the lines to ensure what you're getting is valid:
std::map<int, TimeResponseHashMap* >::iterator it1 = outer_pending_response_map.find(u16SessionID);
if ( it1 != outer_pending_response_map.end())
{
TimeResponseHashMap *theMap = it1->second;
theMap->Find((int)u16MessageID, resp);
}
else
{
// you fill in what happens if the find fails
}
The code above saves it1->second
to a value (theMap
) that you can inspect easily to see if it is correct.
Upvotes: 1