这两个几乎相同的代码有什么不同?



此代码给出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中擦除后的下一个元素。

相关内容

  • 没有找到相关文章

最新更新