vector<CBase*>::iterator aIter;
for (aIter = agents.begin(); aIter != agents.end(); ++aIter) // agents
is vector<CBase*>
{
CBase* a = *aIter;
a->memberFunction() // in here, I push new'd derived pointers onto
agents. agents.size() changes!
}
What I am finding is that, as I iterate, eventually, *aIter becomes a
CBase* object (which is further confusing, since it is an abstract
class)...I should only ever see derived classes pushed onto "agents".
Is there some fundamental thing I have overlooked in the STL in
regards to iterating over a container while it changes size? (or that
contains pointers to derived classes?) The obvious conclusions can not
be reached (ie there is absolutely NO reference to a "CBase* var = new
CBase()" anywhere in my code, and it couldn't happen anyway, because
its an ABC. So..why then does "agents" eventually iterate to these
unknown, unusable CBase* pointers?
- Hanzo
Calling push_back() on a vector may invalidate any existing iterators for
that vector - you would appear to have undefined behaviour, but it's hard to
say without seeing some _real_ code that illustrates the problem.
NeilB
No, but individual containers have restrictions.
With std::vector, any item insertion may invalidate all iterators
that refer to a container's elements. This can only be prevented
if you know the maximum size of the container and call
vector::reserver(maxSize) before creating the iterators.
Solutions to this include:
- using std::list instead of std::vector for your list of agents
- using an item index instead of iterators:
for( AgentsType::size_type i = 0 ; i != vector.size() ; ++i )
I hope this helps,
--
Ivan Vecerina, Dr. med. <> http://www.post1.com/~ivec
Soft Dev Manger, xitact <> http://www.xitact.com
Brainbench MVP for C++ <> http://www.brainbench.com
Hanzo> vector<CBase*>::iterator aIter;
Hanzo> for (aIter = agents.begin(); aIter != agents.end(); ++aIter)
Hanzo> // agents is vector<CBase*>
Hanzo> {
Hanzo> CBase* a = *aIter;
Hanzo> a-> memberFunction() // in here, I push new'd derived pointers onto
Hanzo> // agents. agents.size() changes!
Hanzo> }
Hanzo> What I am finding is that, as I iterate, eventually, *aIter becomes a
Hanzo> CBase* object (which is further confusing, since it is an abstract
Hanzo> class)...I should only ever see derived classes pushed onto "agents".
Hanzo> Is there some fundamental thing I have overlooked in the STL in
Hanzo> regards to iterating over a container while it changes size?
Yes. If you append an element to a vector, and doing so causes the vector
to be reallocated, it invalidates all iterators that refer to vector
elements.
The easiest way to solve this problem is to use indices instead
of iterators in your loop:
vector<CBase*>::size_type aIndex;
for (aIndex = 0; aIndex != agents.size(); ++i) {
agents[i]->memberfunction();
}
--
Andrew Koenig, a...@research.att.com, http://www.research.att.com/info/ark