此代码给出Heap-Use-After-Free错误
for (auto it = mp.begin();it != mp.end();it++)
{
if(it->second+ttl<=currentTime)
{
mp.erase(it);
}
}
但是这个代码
for (auto it = mp.begin();it != mp.end();)
{
if(it->second+ttl<=currentTime)
{
mp.erase(it++);
}
else
{
++it;
}
}
不返回错误。你能解释一下原因吗?在我看来,两者基本上是一样的。请帮助
第一个删除it
的元素,使所有标准容器中的it
无效。之后执行it++
会使程序产生未定义行为。
第二个可能有效,这取决于您使用的容器。
- 例如,如果您使用
*map
,则没关系,因为it++
返回迭代器的当前值,但在内部将其步进以指向下一个元素。该迭代器不受erase
. 的影响。 - 如果你使用
vector
,它有未定义的行为,因为it++
之后的迭代器将被erase
无效。
要使它适用于任何类型的标准容器,将erase
返回的迭代器赋值给it
。
for (auto it = mp.begin(); it != mp.end();) {
if (it->second + ttl <= currentTime) {
it = mp.erase(it);
} else {
++it;
}
}
如果你有unordered_map
,那么从c++ 20开始,我建议使用std::erase_if (std::unordered_map)
来代替:
std::erase_if(mp,
[&](const auto& data) { return data.second + ttl <= currentTime; });
在第一种情况下,擦除后,'it'变为mp.end()
对于map或未定义的unordered_map
,给出错误。在第二种情况下,使用mp.erase(it++)
,这使得'it'指向mp
中擦除后的下一个元素。