Reputation: 4873
Given an STL container (you may also take boost::unordered_map
and boost::multi_index_container
into account) that is non-contiguous, is it guaranteed that the memory addresses of the elements inside the container never changes if no element is removed, (but new ones can be added)?
e.g.
class ABC { };
//
//...
//
std::list<ABC> abclist;
ABC abc;
abclist.insert(abc);
ABC * abc_ptr = &(*abclist.begin());
In other word will abc_ptr
be pointed to abc
throughout the execution, if I do not remove abc
from abc_list
.
I am asking this because I am going to wrap the class ABC
in C++/Cli, so I need pointers to the ABC
instances in the wrapper class. ABC is a simple class and I want the container to handle the memory. If the answer is no then I will use std::list<ABC*>
.
Upvotes: 23
Views: 9562
Reputation: 306
As Armen mentioned std::list, std::set, and std::map are guaranteed to only invalidate the removed iterator. In the case of boost::unodered_map, the modifiers may indeed invalidate iterators.
http://www.boost.org/doc/libs/1_38_0/doc/html/boost/unordered_map.html
Upvotes: 5
Reputation: 300399
The C++ Standard places stringent rules on the validity of references / iterators. For each container, each method documents which elements may be moved (invalidating references and iterators).
The Node Based Containers: list
, map
, set
, multimap
and multiset
guarantee that references and iterators to elements will remain valid as long as the element is not removed from the container.
Your use case is therefore one of the corner cases where using a list
for storage is good, because of the invalidation guarantees that list offer.
Upvotes: 5
Reputation: 133122
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.
Upvotes: 31