Search code examples
c++multithreadingiteratorerase

C++ remove std::list element in loop issue


Good day. I want to understand, why this works good:

    std::list<Contact>::iterator it = contacts.begin();

    while (it != contacts.end()) {
        if ((*it).status == Contact::Status::disconnected) {
            (*it).handler.detach();
            it = contacts.erase(it);
        }
        else {
            it++;
        }   
    }

but this causes crash with message "abort() has been called":

    contacts.remove_if([](Contact c) {
        if (c.status != Contact::Status::disconnected)
            return false;

        c.handler.detach();

        return true;
    });

All this executes in separated thread inside critical section. List and critical section declared globally as:

CRITICAL_SECTION criticalSection;
std::list<Contact> contacts;

Solution

  • In your lambda for remove_if, you're passing in a copy of the Contact, and detaching from that one. The original in the list does not get detached. Pass in a reference instead: remove_if([](Contact &c).