删除标准地图中的重复值

Deleting duplicate values in std map

本文关键字:标准 地图 删除      更新时间:2023-10-16

我有一个

map<char,my_class*> mymap;

内容如下。

mymap[0]=('a', 0x1);
mymap[1]=('b',0x2);
mymap[3]=('c',0x3);
mymap[4]=('d',0x1);

如您所见,我们对键"a"和"d"具有相同的值。 我有一个 for 循环来删除地图中的指针。

for ( it=mymap.begin() ; it != mymap.end(); it++ ){
  delete it->second;
}

它崩溃,因为它试图删除0x1两次。我试过这样做

for ( it=mymap.begin() ; it != mymap.end(); it++ ){
  if(!it->second){
      delete it->second;
      it->second = NULL;
  }
}

即使这样也会尝试将指针设置为 NULL 两次,从而导致异常。删除地图中上述重复值的最佳方法是什么?

NPE涉及shared_ptr的答案很好。但是如果你被迫使用真正的指针,我可能会这样做:

set<my_class*> values;
for (it=mymap.begin(); it != mymap.end(); it++)
{
  // insert.second will be false if the value is already in the set
  if (values.insert(it->second).second)
    delete it->second;
}
// Make sure you do something with mymap to ensure you don't double-delete later!

我的建议是将shared_ptr<my_class>保留在您的地图中,并完全回避这个问题。

如果你不能做到这一点,你需要保留一个辅助容器(例如set)你已经解除分配的指针。然后,您将在迭代地图时查阅并更新该容器。

如果你不想要重复的第二个条目,那么也许最好的解决方案是一开始就不要插入它们。 这我能想到的最干净的解决方案是使用提升双地图。 我宁愿认为这种行为会让但是,插入第二个条目的用户。

或者(假设你不能使用shared_ptr),即解构地图时最简单的解决方案是创建包含所有元素的临时std::set<MyClass*>,以及然后从中删除。 (std::set确保没有重复)。

当我在做这件事时:你的第二个解决方案失败的原因不是因为您将指针设置为 null 两次;什么都没有错了。 这是因为您有两个不同的指针到同一对象;将第一个设置为 null 不会修改其次,所以你最终仍然试图删除相同的对象两次。

如果您存储实例或使用智能指针,它会更简单。Std::Map 有自己的指向对象的内部指针,您可以通过依赖其他人对你的对象的处理来省去麻烦。Boost库包含多个智能指针。如果使用侵入式引用计数智能指针,则对象在从地图中删除时会自动销毁。

然后,您将能够使用 erase 函数从映射中删除该值,然后在调用析构函数链后删除您的对象(如果它是最后一个引用)。