我有一个
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两次,这会导致异常。 在地图中删除上述重复值的最佳方法是什么?
答案 0 :(得分:5)
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!
答案 1 :(得分:4)
我的建议是将shared_ptr<my_class>
保留在地图中,并完全回避问题。
如果你不能这样做,你需要保留一个你已经解除分配的辅助容器(例如set
)指针。然后,当您在地图上进行迭代时,您将咨询并更新该容器。
答案 2 :(得分:2)
如果您不想复制第二个条目,那么也许是 最好的解决方案是不要插入它们。该 我能想到的最干净的解决方案是使用 提升bimap。我宁愿认为这种行为会令人惊讶 但是,插入第二个条目的用户。
或者(假设你不能使用shared_ptr
),
解构地图时最简单的解决方案就是创建
包含所有元素的临时std::set<MyClass*>
和
然后从中删除。 (std::set
确保没有重复项。)
虽然我在这里:你的第二个解决方案失败的原因不是 因为你要设置一个指向null的指针两次;什么也没有 错了。这是因为你有两个不同的指针 同一个对象;将第一个设置为null不会修改 第二,所以你仍然最终试图删除相同的对象 两次。
答案 3 :(得分:0)
如果您存储实例或使用了智能指针,那会更简单。 Std :: Map有自己的内部指针指向你的对象,你可以依靠别人对你的对象的处理来节省头痛。 Boost
库包含几个智能指针。如果您使用侵入式引用计数smartpointer,那么当您的对象从地图中删除时,它可以自动销毁。
然后,您将能够使用erase函数从地图中删除该值,然后在调用析构函数链之后删除您的对象(如果它是最后一个引用)。