Home > database >  How These 2 Almost Same code are different?
How These 2 Almost Same code are different?

Time:05-19

This Code is giving error Heap-Use-After-Free

for (auto it = mp.begin();it != mp.end();it  )
{
    if(it->second ttl<=currentTime)
    {
        mp.erase(it);
    }
}

But this code

for (auto it = mp.begin();it != mp.end();)
{
    if(it->second ttl<=currentTime)
    {
        mp.erase(it  );
    }
    else
    {
          it;
    }
}

Does Not give ans error. Can you please explain why? Both look basically the same to me. Please Help

CodePudding user response:

The first one erases the element at it which invalidates it in all standard containers. Doing it afterwards makes the program have undefined behavior.

The second one may work depending on which container you use. If you for example use a *map, it's ok because it returns the next iterator, which is unaffected by the erase. If you use a vector it has undefined behavior because it returns an iterator that will have been invalidaded by the erase.

To make it work with any type of standard container, assign the iterator returned by erase to it.

for (auto it = mp.begin(); it != mp.end();) {
    if (it->second   ttl <= currentTime) {
        it = mp.erase(it);
    } else {
          it;
    }
}

If you have an unordered_map, then since C 20, I recommend using
std::erase_if (std::unordered_map) instead:

std::erase_if(mp,
    [&](const auto& data) { return data.second   ttl <= currentTime; });

CodePudding user response:

In the first, after erase, 'it' becomes mp.end() for map or undefined for unordered_map, giving the error. The second uses mp.erase(it ), which makes 'it' points to next element in mp after erase.

  • Related