title: issue with std::map std::find
body: <p>I have working c++ deamon. The problem is that daemon crash one or two times per month. As you see from GDB output below its happens when daemon search for <code>unsigned int</code> sessionID at <code>std::map &lt;unsigned int const, SessionID*&gt;</code> container. I can not reproduce the problem and think that its maybe something wrong with data from users (maybe <code>std::sting cookie_ssid</code> have some unexpected data and after conversion with <code>strtoul</code>something going wrong. (<em>know, that this is not the correct way to get <code>unsigned int</code></em> ) </p>
  
  <p>I have only <code>.core</code> file after daemon crash. and see that problem at <code>if (!_M_impl._M_key_compare(_S_key(__x), __k))</code>. Any ideas how to solve this problem? Many thanks.</p>
  
  <p>GDB output: </p>
  
  <pre><code>#0  std::_Rb_tree&lt;unsigned int, std::pair&lt;unsigned int const, SessionID*&gt;, std::_Select1st&lt;std::pair&lt;unsigned int const, SessionID*&gt; &gt;, std::less&lt;unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, SessionID*&gt; &gt; &gt;::find (this=0x529df15c, __k=@0x7f5fab7c)
      at stl_tree.h:1376
  ##########
  1376            if (!_M_impl._M_key_compare(_S_key(__x), __k))
  ##########
  #0  std::_Rb_tree&lt;unsigned int, std::pair&lt;unsigned int const, SessionID*&gt;, std::_Select1st&lt;std::pair&lt;unsigned int const, SessionID*&gt; &gt;, std::less&lt;unsigned int&gt;, std::allocator&lt;std::pair&lt;unsigned int const, SessionID*&gt; &gt; &gt;::find (
      this=0x529df15c, __k=@0x7f5fab7c) at stl_tree.h:1376
  #1  0x0805e6be in TR::find_session (this=0x529df110,
      cookie_ssid=@0x47ef3614, ptr_to_ptr_session=0x7f5fac7c)
      at stl_map.h:542
  </code></pre>
  
  <p>Function <code>TR::find_session</code> released like this: </p>
  
  <pre><code>bool TR::find_session ( const std::string &amp;cookie_ssid, SessionID **ptr_to_ptr_session )
  {
      unsigned int uint_sessionid = std::strtoul ( cookie_ssid.c_str(),NULL,0);
  
  MUTEX_map_sessionids.lock_reading();
      std::map&lt;unsigned int, SessionID*&gt;::iterator it_sessionids = map_sessionids.find( uint_sessionid );
  
      if ( it_sessionids != map_sessionids.end() )
      { // exists
          *ptr_to_ptr_session = it_sessionids-&gt;second;
          MUTEX_map_sessionids.unlock();
          return true;
      }
  
  MUTEX_map_sessionids.unlock();  
  return false;   
  }
  </code></pre>
  
  <p><strong>EDIT</strong>
  My cleanup function that working at separated thread (one time per minute or 5 minutes). As requested at comments. I am not sure with this function. Maybe its buggy....</p>
  
  <pre><code>void TR::cleanup_sessions () // not protected from multithread using! used only at one thread
  {
  std::list&lt;SessionID*&gt; list_to_clean; // tmplary store sessions to delete
  
  MUTEX_map_sessionids.lock_reading();
  std::map&lt;unsigned int, SessionID*&gt;::iterator it_sessionids = map_sessionids.begin();
  MUTEX_map_sessionids.unlock();
  
  while ( true )
  {
      MUTEX_map_sessionids.lock_writing();
      if (it_sessionids == map_sessionids.end() )
      {
          MUTEX_map_sessionids.unlock();
          break;
      }
  
      SessionID *ptr_sessionid = it_sessionids-&gt;second;
  
      time_t secondsnow = time (NULL);
  
      ptr_sessionid-&gt;MUTEX_all_session.lock_reading();
      time_t lastaccesstime = ptr_sessionid-&gt;last_access_time;
      size_t total_showed = ptr_sessionid-&gt;map_showed.size(); 
      ptr_sessionid-&gt;MUTEX_all_session.unlock();
  
  
      if ( lastaccesstime and secondsnow - lastaccesstime &gt; LOCALSESSION_LIFETIME_SEC ) // lifetime end!
      {
          // delete session from map
          map_sessionids.erase( it_sessionids++ ); // Increments the iterator but returns the original value for use by erase
          MUTEX_map_sessionids.unlock();              
  
  
          list_to_clean.push_back ( ptr_sessionid ); // at the end
      }
      else if ( total_showed == 0 and secondsnow - lastaccesstime &gt; 36000 ) // not active for N secontes
      {
          map_sessionids.erase( it_sessionids++ ); // Increments the iterator but returns the original value for use by erase
          MUTEX_map_sessionids.unlock();
  
          // add pointer to list to delete it latter
          list_to_clean.push_back ( ptr_sessionid ); // at the end            
      }
      else
      {
          ++it_sessionids; // next
          MUTEX_map_sessionids.unlock();              
      }
  
  }
  
  // used? pause
  if ( !list_to_clean.empty() ) 
  {
      //sleep(1);
  }
  
  // cleanup session deleted from working map
  while ( !list_to_clean.empty() )
  {
      SessionID *ptr_sessionid_to_delete = list_to_clean.front();
      list_to_clean.pop_front();
  
      ptr_sessionid_to_delete-&gt;MUTEX_all_session.lock_writing(); // protected lock session mutex. can not delete session if its already locked. (additational protection)
      ptr_sessionid_to_delete-&gt;cleanup();
      delete ptr_sessionid_to_delete;
  }
  </code></pre>
  
  <p>}</p>
  
  <p><strong>NOTE</strong> as you can see on every itteration I lock/unlock map_sessions, because other threads at this time find/insert new sessions and its critical, because users can not wait.</p>