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.