[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Erasing from middle of a list problem

Angus

11/1/2008 10:52:00 AM

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
3 Answers

fungus

11/1/2008 11:02:00 AM

0

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

11/1/2008 11:07:00 AM

0

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.

11/1/2008 2:00:00 PM

0

Angus <anguscomber@gmail.com> wrote:

> 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?

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.