Reputation: 1168
I am using vector::erase() function to delete the the first element in the vector until it is empty but my compiler is giving me an "Invalid Pointer Operation" error.
I have a vector of class-defined objects, foo, called bar. I am deleting elements one by one like so:
for(int i = 0; i < bar.size(); i++){
if(!bar.empty()){
bar.erase(bar.begin());
}
}
When I run my program, it only completes one iteration (no matter the size) and breaks on the second. Specifically, it breaks on the STL function _Destroy
template<class _TyDtor> inline
void _Destroy(_TyDtor _FARQ *_Ptr)
{ // destroy object at _Ptr
_DESTRUCTOR(_TyDtor, _Ptr);
}
*note I know there is a clear function that would do this more neatly but this is just a simplified example of something else that I am trying to do
Upvotes: 0
Views: 890
Reputation: 131
The problem is the condition part of the loop bar.size()
which keeps changing in each iteration i.e., decreasing in this example by 1.
It is difficult to say what exactly you are trying to achieve within the loop but if you want to execute the loop bar-size ()
times then use the follow logic:
const size_t vecSize = bar.size ()
for(int i = 0; i < vecSize ; i++)
{ ..... }
Otherwise if you want to execute the loop till bar-size ()
is empty, then use the while
loop as follows:
while (bar.size > 0)
{ ..... }
Upvotes: 0
Reputation: 477580
As always when modifying a range while traversing the range, you cannot unconditionally increment the loop counter.
Consider the simple example of a two-element set. When i
is 0
, you remove the first element and increment i
. Now i
is 1
and bar.size()
is 1
, and the loop exits, failing to delete the second element.
The standard solution is to make the increment conditional on not modifying the container:
for (int i = 0; i < bar.size(); /* no increment here */) {
if (!bar.empty()) {
bar.erase(bar.begin());
} else {
++i;
}
}
When you do modify the container by erasing an element, i
stays constant but the range moves one element closer to it. Also incrementing i
would be double-counting.
(This is an extremely common mistake, though usually it's expressed in terms of iterators, e.g. here or here or here.)
Upvotes: 2