0

I am having an issue and I think it is because of the iterators being invalidated. However I use the iterator from erase() to resume iterating other the structure. When erase() when I try to increment after erase() is called the first time I get the following error

'vector iterator not incrementable '

std::map<uint32_t, std::vector<std::pair<boost::uuids::uuid, tvshared::SecureIPCCallbackHandlePtr>>>::iterator itMap;
std::vector<std::pair<boost::uuids::uuid, tvshared::SecureIPCCallbackHandlePtr>>::iterator itVector;
{
    tvstd::lock_guard_mutex l(m_ConnectionsMutex);
    itMap = m_Connections.find(static_cast<uint32_t>(pcp->ProcessID()));
    if (itMap != m_Connections.end())
    {
        for (itVector = itMap->second.begin(); itVector != itMap->second.end(); ++itVector)
        {
            if (commadUUID == itVector->first)
            {
                itVector->second.reset();
                itVector = m_Connections[static_cast<uint32_t>(pcp->ProcessID())].erase(itVector);
            }               
        }
    }
}

Can anyone see where I am going wrong?

CodersSC
  • 710
  • 2
  • 13
  • 29
  • 2
    possible duplicate of [iterate vector, remove certain items as I go](http://stackoverflow.com/questions/1604588/iterate-vector-remove-certain-items-as-i-go) – Cory Kramer May 19 '15 at 11:38
  • 2
    Hint: What happens if your `erase` call erased the last element in the vector? – T.C. May 19 '15 at 11:40
  • @T.C. ah yeah it is because im erasing in the middle of the list if i do it at the end it will be fine... so what I have done here is put a break once I erase. This solves it. – CodersSC May 19 '15 at 11:43
  • Also, that second lookup is completely unnecessary. Just use `itMap`. – T.C. May 19 '15 at 11:44

2 Answers2

0

erase returns an iterator pointing to the new location of the element that followed the last element erased by the function call. This is the container end if the operation erased the last element in the sequence.

so if you erase you do not need to increment your iterator

 for (itVector = itMap->second.begin(); itVector != itMap->second.end(); )
    {
        if (commadUUID == itVector->first)
        {
            itVector->second.reset();
            itVector = m_Connections[static_cast<uint32_t>(pcp->ProcessID())].erase(itVector);
        }
      else
      {
           ++itVector
      }               
 }
Alexander
  • 698
  • 6
  • 14
0

This solved my issue, I just have to call break after i erase but once i erase i do not need to loop to the end of the list. (@Aleexander solution also works)

std::map<uint32_t, std::vector<std::pair<boost::uuids::uuid, tvshared::SecureIPCCallbackHandlePtr>>>::iterator itMap;
std::vector<std::pair<boost::uuids::uuid, tvshared::SecureIPCCallbackHandlePtr>>::iterator itVector;
{
    tvstd::lock_guard_mutex l(m_ConnectionsMutex);
    itMap = m_Connections.find(static_cast<uint32_t>(pcp->ProcessID()));
    if (itMap != m_Connections.end())
    {
        for (itVector = itMap->second.begin(); itVector != itMap->second.end(); ++itVector)
        {
            if (commadUUID == itVector->first)
            {
                itVector->second.reset();
                itVector = m_Connections[static_cast<uint32_t>(pcp->ProcessID())].erase(itVector);

                break;
            }
        }
    }
}
CodersSC
  • 710
  • 2
  • 13
  • 29