Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Erasing from middle of a list problem

9 views
Skip to first unread message

Angus

unread,
Nov 1, 2008, 6:52:00 AM11/1/08
to
If I want to erase all list items with a value of say 3 as below:

std::list<int> mylist;
mylist.push_back(3);
mylist.push_back(4);
mylist.push_back(5);
mylist.push_back(6);

for(std::list<int>::iterator it = mylist.begin(); it !=
mylist.end(); ++it) {
if(*it == 3) {
std::cout << "deleting 3" << std::endl;
mylist.erase(it);
}
}

I get an access violation in the loop iteration after an erase. What
is the recommended way to deal with this? ie iterate through a
container removing elements which meet a criterion? remove?

A

fungus

unread,
Nov 1, 2008, 7:02:26 AM11/1/08
to
On Nov 1, 11:52 am, Angus <anguscom...@gmail.com> wrote:
>
> I get an access violation in the loop iteration after an erase.

Yep, you just freed the memory referenced by "it".

> What
> is the recommended way to deal with this? ie iterate through a
> container removing elements which meet a criterion?  remove?
>

std::list<int>::iterator it = mylist.begin();
while (it != mylist.end()) {


if(*it == 3) {
std::cout << "deleting 3" << std::endl;

it = mylist.erase(it);
}
else {
++it;
}
}

Marcel Müller

unread,
Nov 1, 2008, 7:06:38 AM11/1/08
to
Angus schrieb:

> for(std::list<int>::iterator it = mylist.begin(); it !=
> mylist.end(); ++it) {
> if(*it == 3) {
> std::cout << "deleting 3" << std::endl;
> mylist.erase(it);
> }
> }
>
> I get an access violation in the loop iteration after an erase.

Of course, you just invalidated your iterator by erasing its element.

> What
> is the recommended way to deal with this?

erase returns an iterator to the next valid element.


> ie iterate through a
> container removing elements which meet a criterion? remove?

The algorithm remove_if will do the job for you.


Marcel

Daniel T.

unread,
Nov 1, 2008, 10:00:29 AM11/1/08
to
Angus <angus...@gmail.com> wrote:

The answers to date missed something important.

mylist.remove( 3 );

will do exactly what you want.

The 'remove' and 'remove_if' algorithms are highly inefficient if used
on a list, there is no reason to reseat values in nodes when dealing
with a linked list.

Writing the loop yourself is wasteful in this case.

0 new messages