In below code I am filling a map m
with elements from another container vv
. I am using a pointer to the current element in the map and that element/object is being further manipulated.
struct obj_t { vector<int> w1, w2, w3, ... };
map<int, obj_t> m;
vector<vector<int> vv;
for (vector<int> &v : vv) {
obj_t *p = &m[v[0]]; // create entry at key = v[0] if none existed
p->w1.push_back(v[1]);
p->w2.push_back(v[2]);
// many fields w3, w4, ... so using pointer may be "efficient"
}
Question: Is this pointer access safe? Is the element inside m
that is being manipulated, guaranteed to retain its address through each access inside the loop? And from one iteration to another? (although not required in this example).
I understand that you should normally not use pointers to elements in containers, since these may be moved around by other parts of the "program" / "runtime". But I guess that inside a tight context like this, where no other manipulation of the map m
takes place, this kind of pointer access is guaranteed to be safe. Is that correct?
The suspicion that it might not be like that would come from something like this where some_large_allocation()
may cause memory objects to be relocated by the operating system:
for (vector<int> &v : vv) {
obj_t *p = &m[v[0]]; // creates entry at key = v[0] if none existed.
p->w1.push_back(v[1]);
// some_large_allocation() // can force elements of m to be relocated?
p->w2.push_back(v[2]); // *illegal* m and/or the element pointed to was moved
...
}
UPDATE (written here, since marked as dupe, closed for answers)
To this question, Pointers to elements of STL containers, the accepted answer states:
std::list, std::set, and std::map guarantee that the iterators (including simple pointers) will not be invalidated when a new element is added or even removed.