I am debugging a big C++98 application and I am obtaining a SIBGUS
error when a method tries to increment a std::map::iterator
.
By putiing traces, I have discovered that the method in question removes elements from the mentioned map (indireclty, by calling other methods that call other methods and so on...), so I suspect that the problem is to been iterating over the map while deleting its elements.
I have been searching the proper way to iterate over a std::map
and delete items safelly, and I have found this:
for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
if (must_delete)
{
m.erase(it++); // or "it = m.erase(it)" since C++11
}
else
{
++it;
}
}
Code quoted from How to remove from a map while iterating it?
I have some questions about this:
Is it actually necessary to distinguis between deleting elements or not, taking into account that the iterator is going to be increased in any case?
Is the following code snippet equivalent to the above one, in terms of safety?
for (auto it = m.cbegin(); it != m.cend() /* not hoisted */; /* no increment */)
{
if (must_delete)
{
m.erase(it);
}
it++;
}
The method that is producing the SIGBUS
follows the following pattern:
std::map<..., ...>::iterator it = myMap.begin(); // myMap is an instance attribute and can be accessed by any class method.
while(it != myMap.end() {
if(somethingHappens())
doSomethingThatMightDeleteMapElements(); // this can (or not) delete 'myMap' elements.
it++; // The error occurs here
}
Since the deletion is performed by other method/s, I cannot distinguis if an element has been deleted or not (unless I return a boolean value or similar). Is this potentially unsafe?