[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

STL map question

Posted on 2007-08-01
8
Medium Priority
?
292 Views
Last Modified: 2010-04-01
Hi Experts,

I asked a similar question before for solving another question.  Here, the following function gets into a infinite loop.  I think it is the result of the    
sl_it = (*vsm_it).second.begin()  or   vsm_it = m_viewServantMap.begin()

This fix was suggested as part of the solution to the following problem. How to correct it.



http://www.experts-exchange.com/Programming/Languages/CPP/Q_22714113.html

void ClientRep::removeServantFromList( Servant *servant )
{
  PostSoftwareLog( OTP_LOG_INFO, LOG_SOURCE, "Removing servant from list" );
  ViewServantMap_Iter vsm_it = m_viewServantMap.begin();

  while (vsm_it != m_viewServantMap.end())
    {
      ServantList_Iter sl_it = (*vsm_it).second.begin();
      while( sl_it != (*vsm_it).second.end() ) {
        if( *sl_it == servant ) {
          delete (*sl_it);
          sl_it = (*vsm_it).second.erase(sl_it);
          if (sl_it != (*vsm_it).second.end())
            --sl_it;
        }
        sl_it = (*vsm_it).second.begin();
      }
      vsm_it = m_viewServantMap.begin();
    }
}

The gdb backtrace shows this.

#0 0x08070e8a in std::list<Servant*, std::allocator<Servant*> >::begin ()
#1  0x08070c43 in ClientRep::removeServantFromList ()


0
Comment
Question by:ambuli
8 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 19611318
At the end of each loop, you're rewinding to the beginning - you'll never get to the end of the container, and that's why you have an infinite loop.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 19611336
Try this :

void ClientRep::removeServantFromList( Servant *servant )
{
  PostSoftwareLog( OTP_LOG_INFO, LOG_SOURCE, "Removing servant from list" );
  ViewServantMap_Iter vsm_it = m_viewServantMap.begin();

  while (vsm_it != m_viewServantMap.end())
    {
      ServantList_Iter sl_it = (*vsm_it).second.begin();
      while( sl_it != (*vsm_it).second.end() ) {
        if( *sl_it == servant ) {
          delete (*sl_it);
          sl_it = (*vsm_it).second.erase(sl_it);
          --sl_it;
        }
        ++sl_it;
      }
      ++vsm_it;
    }
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 19611359
I'd make that

  while (!m_viewServantMap.empty())
    {
      ServantList_Iter sl_it = (*vsm_it).second.begin();
      while( (*vsm_it).second.empty() ) {
        if( *sl_it == servant ) {
          delete (*sl_it);
          sl_it = (*vsm_it).second.erase(sl_it);
        }
        sl_it = (*vsm_it).second.begin();
      }
      vsm_it = m_viewServantMap.begin();
    }
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
LVL 53

Expert Comment

by:Infinity08
ID: 19611385
That code also has an infinite loop, jkr. I think the point of the function is to only erase one specific servant.
0
 

Author Comment

by:ambuli
ID: 19611844
Yes, deleting one specific servant from the map is what the function is doing.  
0
 

Author Comment

by:ambuli
ID: 19611858
From JKR's comment on the last question
"When you erase an element in STL containers all iterators become invalid at that moment (except for 'list' iterators)"

Doesn't it still applies to

void ClientRep::removeServantFromList( Servant *servant )
{
  PostSoftwareLog( OTP_LOG_INFO, LOG_SOURCE, "Removing servant from list" );
  ViewServantMap_Iter vsm_it = m_viewServantMap.begin();

  while (vsm_it != m_viewServantMap.end())
    {
      ServantList_Iter sl_it = (*vsm_it).second.begin();
      while( sl_it != (*vsm_it).second.end() ) {
        if( *sl_it == servant ) {
          delete (*sl_it);
          sl_it = (*vsm_it).second.erase(sl_it);
          --sl_it;
        }
        ++sl_it;
      }
      ++vsm_it;
    }
}
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 1600 total points
ID: 19612065
I assumed that (*vsm_it).second is a list, so for the inner loop there are no problems, since we use the returned iterator from erase.
The outer loop doesn't have a problem either, since there is never anything erased from the map.
0
 
LVL 15

Assisted Solution

by:efn
efn earned 400 total points
ID: 19614771
For an associative container, an erase operation only invalidates iterators and references to the erased elements.  The associative containers are set, multiset, map, and multimap.  (ISO/IEC 14882:2003, 23.1.2)

For a deque, an erase in the middle invalidates all iterators, but an erase at either end only invalidates iterators to the erased element.  (23.2.1.3)

For lists, an erase only invalidates iterators to the erased element.  (23.2.2.3)

For a vector, an erase only invalidates iterators that point later in the sequence than the erased element.  (23.2.4.3)
0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
Suggested Courses

872 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question