Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么';删除条目映射的最佳方法<;整数,A*>;_C++_Stl_Map - Fatal编程技术网

C++ 什么';删除条目映射的最佳方法<;整数,A*>;

C++ 什么';删除条目映射的最佳方法<;整数,A*>;,c++,stl,map,C++,Stl,Map,我和同事讨论了如何删除地图中的条目 该映射具有int作为索引和指向对象的指针 我说,首先释放对象,然后删除条目。 我的同事说先删除条目,然后释放对象 那最好的办法是什么呢?这个问题有什么窍门吗?先删除对象,然后从地图中删除。否则,您只需要引入一个无意义的中间变量来存储指针。只要您是单线程的,或者在多线程场景中具有适当的锁定,这两种方法在所有实际用途上都是等效的 map<int, A *>::iterator it = mymap.find(1); if (it != mymap.en

我和同事讨论了如何删除地图中的条目 该映射具有int作为索引和指向对象的指针

我说,首先释放对象,然后删除条目。 我的同事说先删除条目,然后释放对象


那最好的办法是什么呢?这个问题有什么窍门吗?

先删除对象,然后从地图中删除。否则,您只需要引入一个无意义的中间变量来存储指针。只要您是单线程的,或者在多线程场景中具有适当的锁定,这两种方法在所有实际用途上都是等效的

map<int, A *>::iterator it = mymap.find(1);
if (it != mymap.end()) {
  delete it->second;
  mymap.erase(it);
} 
map::迭代器it=mymap.find(1);
if(it!=mymap.end()){
删除它->秒;
我的地图。删除(它);
} 

除非您有多线程环境,否则任何一种方法都可以。经验法则是,一旦函数返回,就不应该剩下悬空指针,也就是说,没有指向刚刚删除的对象的指针


唯一可能出现的问题是,如果您先删除条目,您必须确保拥有指针的临时副本,因为删除条目后您将无法从地图中检索它。

受@Nim启发,第三种方法如何:按值或智能指针在地图中存储对象。然后RAII会自动为您处理所有清理工作


如果您必须使用原始指针,那么这并不重要,只要您确保应用了线程问题所需的任何锁定。

这可能无关紧要

您可能会认为,如果您有两个线程,一个线程试图从映射中删除一个项目,另一个线程试图访问同一个映射,这将很重要。您可能会得出这样的结论:首先从映射中删除该项会更安全,这样其他线程就不会检索到指向已删除对象的指针

但是,如果有多个线程访问同一个映射,则需要使用同步对象(互斥对象,或者如果您在普通Win32中,则使用关键_节)对其进行保护。对于一个线程正在修改集合的非同步多线程使用,std::map是不安全的。因此,如果您已经在移除和删除地图时锁定了地图,那么无论您以何种方式执行操作都无关紧要


话虽如此,如果销毁对象需要很长时间,您可能希望将delete调用移到代码的互斥锁部分之外。在这种情况下,首先将对象的指针存储在临时变量中,删除其在映射中的条目,解锁,然后删除。

保守的方法是先删除指针,然后删除指针

在标准容器中存储一个无效指针值可能导致未定义的行为,至少根据C++标准的段落<强> > [基本.STC.Distaly.DeDeals] / 4 < /Standard >,它禁止任何无效指针值的使用(例如容器内部指针的复制)和<强>[lib.container.requirements],它要求存储在容器中的对象必须是可复制和可分配的


然而,这个问题有点争议。

您应该研究一下如何使用boost的ptr_map。您没有理由为此推出自己的解决方案。一定要听每个人指出多线程访问您的容器的注意事项。

为什么这里的“释放”和“删除”是指“删除”吗是指使用
删除
,还是从映射中删除?嗯……我会选择第三种方式,在映射中存储智能指针,让它担心何时清理(即,何时从容器中删除,并且没有其他引用!)