可以对std :: map中的元素引用无效吗?

时间:2017-11-14 07:55:23

标签: c++ multithreading c++11 std

我有一个多线程应用程序和一个共享资源std::map<KeyType, ElementType>。我使用互斥锁来保护插入,获取和删除。

我的get方法返回对存储元素的引用(返回时解锁),然后我对该元素进行一些操作。

问题:使用存储的元素引用时,另一个线程可能会更改std::map,因此元素将被移动到不同的地址,并且引用将不再有效吗? (我知道某些ADT实现会在调整大小时重新安排ADT。)

2 个答案:

答案 0 :(得分:7)

关联容器(std::map所示)的迭代器失效规则在[associative.reqmts]/9处说明:

  

插入和安置成员不得影响其有效性   迭代器和对容器的引用,以及擦除成员   仅使迭代器和对已擦除元素的引用无效。

因此,如果一个线程插入一个元素,它将不会影响对现有元素的任何引用。但如果它删除了某些东西,其他线程可能会被堵塞。我会说,某些形式的元素锁定是有序的。

答案 1 :(得分:3)

另一个线程可能会删除元素,或者破坏地图,这当然也会使元素无效。

擦除元素只会使迭代器和对此元素的反思无效。插入不会使迭代器或对地图的引用无效。

(这至少是second-hand documentation says - 而且这是我所持有的假设,如果轶事证据很重要,那就永远不会失效。)

还存在另一个问题:通过返回的引用对元素进行操作不是线程安全的。你需要同步,例如每个元素 - 并确保您不违反锁定层次结构。