By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,128 Members | 1,224 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,128 IT Pros & Developers. It's quick & easy.

Weird crasher with std::remove, std::erase

P: n/a
This small piece of code is troubling me.. is there anything wrong
with it??
After calling this method the contents ot the input vector are
completely screwed..
(CCountedCIG_CountZero() applies only to a few elements in the vector)

void UElementVector::ClearZeroCountElements(vector<CCou ntedCIG*>
&ioItemVec)
{
vector<CCountedCIG*>::iterator new_end = remove_if(ioItemVec.begin(),
ioItemVec.end(), CCountedCIG_CountZero());

for (vector<CCountedCIG*>::iterator it = new_end; it !=
ioItemVec.end(); it++)
{
delete *it;
*it = NULL;
}

ioItemVec.erase(new_end, ioItemVec.end());
}
Any help is much apreciated!

regards,
jan

Mar 24 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
In article <11**********************@l75g2000hse.googlegroups .com>,
gr****@barnholt.net wrote:
This small piece of code is troubling me.. is there anything wrong
with it??
After calling this method the contents ot the input vector are
completely screwed..
(CCountedCIG_CountZero() applies only to a few elements in the vector)

void UElementVector::ClearZeroCountElements(vector<CCou ntedCIG*>
&ioItemVec)
{
vector<CCountedCIG*>::iterator new_end = remove_if(ioItemVec.begin(),
ioItemVec.end(), CCountedCIG_CountZero());

for (vector<CCountedCIG*>::iterator it = new_end; it !=
ioItemVec.end(); it++)
{
delete *it;
*it = NULL;
}

ioItemVec.erase(new_end, ioItemVec.end());
}
<nodThe problem is that remove_if works just by overwriting elements
that no longer belong in the sequence. It doesn't swap them to the end.
What is most likely happening is that you are overwriting the pointers
you want to delete. And then you are deleting copies of the pointers
you want to keep. A subsequent dereference leads to a crash.

You could do a two-pass operation where the first pass did:

1. Check if you want to delete, and if so:
2. delete
3. null pointer

transform could possibly be employed for the first pass.

And then the second pass could call remove (if null pointer).

Or you could write your own algorithm which combines these passes into a
single pass.

-Howard
Mar 24 '07 #2

P: n/a
On Mar 24, 9:41 pm, Howard Hinnant <howard.hinn...@gmail.comwrote:
<nodThe problem is that remove_if works just by overwriting elements
that no longer belong in the sequence. It doesn't swap them to the end.
What is most likely happening is that you are overwriting the pointers
you want to delete. And then you are deleting copies of the pointers
you want to keep. A subsequent dereference leads to a crash.

D'oh! Thanks for the hint -- carefully re-reading the docs it's all
there..

| Remove_if removes from the range [first, last) every element x such
that pred(x) is true.
| That is, remove_if returns an iterator new_last such that the range
[first, new_last)
| contains no elements for which pred is true. [1] The iterators in
the range [new_last, last)
| are all still dereferenceable, but the elements that they point to
are unspecified.
| ..
cheers,
jan

Mar 25 '07 #3

P: n/a
On Mar 25, 11:44 am, gro...@barnholt.net wrote:
On Mar 24, 9:41 pm, Howard Hinnant <howard.hinn...@gmail.comwrote:
<nodThe problem is that remove_if works just by overwriting elements
that no longer belong in the sequence. It doesn't swap them to the end.
What is most likely happening is that you are overwriting the pointers
you want to delete. And then you are deleting copies of the pointers
you want to keep. A subsequent dereference leads to a crash.

D'oh! Thanks for the hint -- carefully re-reading the docs it's all
there..

| Remove_if removes from the range [first, last) every element x such
that pred(x) is true.
| That is, remove_if returns an iterator new_last such that the range
[first, new_last)
| contains no elements for which pred is true. [1] The iterators in
the range [new_last, last)
| are all still dereferenceable, but the elements that they point to
are unspecified.
| ..

cheers,
jan
This behavior surprises me.I have read the source code for remove
family but I do not understand how they can be useful!!!????
remembering that they won`t work with map whose elements are none-
assignable 'pair's.

Mar 25 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.