Here is the scenario:
1) using an unordered_map<int, vector<MyClass*>*>
let's say I add keys 1, 2, ... 8
2) all keys are set with a vector at program initialization and nothing more is added or deleted
3) I have 8 threads, where thread1 accesses key[1], thread2 accesses key[2], ... thread8 accesses key[8] (i.e. the thread number can only access that key number and no other key)
Sometimes I re-assign the value vector* to another heap allocated collection. (i.e. thread1 performs key[1] = new vector<MyClass*>
)
I believe this will be thread safe, am I correct? If not, I suppose I will use concurrent_unordered_map.
thanks.
The answer to this question can be found in [res.on.data.races]/3
:
A C++ standard library function shall not directly or indirectly modify objects (1.10) accessible by threads other than the current thread unless the objects are accessed directly or indirectly via the function’s non- const arguments, including this.
Furthermore, [container.requirements.dataraces]/1
states:
For purposes of avoiding data races (
[res.on.data.races]
), implementations shall consider the following functions to beconst
:begin
,end
,rbegin
,rend
,front
,back
,data
,find
,lower_bound
,upper_bound
,equal_range
,at
and, except in associative or unordered associative containers,operator[]
.
Since unordered_map::operator[] is non-const, it is legal for an implementation to modify the unordered_map
when a call to operator[]
occurs. You should instead use unordered_map::find, which is explicitly required to be treated as const
, and hence will not modify the unordered_map
:
map.find(key)->second = new vector<MyClass*>;
(As a side note, your suggested design looks like a recipe for memory leaks. Why not make it be a unordered_map<int, std::unique_ptr<vector<MyClass*>>>
, or unordered_map<int,vector<MyClass*>>
?)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With