STL list -- Access Violation on remove() -- WHY?

This is a contrived example from my real program.  I am new
to STL.

Why does this give me an Access Violation in the final
for() loop?  Is there some sort of reset that I am supposed
to call between the loops?  

Later, I want to remove specific entries from the list, display
the list, and when the program exits, I want to prevent the memory leak and delete all the remaining entries.  





// stllisttest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iomanip.h>
#include <list>
using namespace std;

class CData {
public:
      int x;
      int y;
};

typedef list<CData*> DATALIST;

int main(int argc, char* argv[])
{
      CData* pData;
      DATALIST dataList;
      DATALIST::iterator i;
      int n;

      for (n = 0; n < 10; n++)
      {
            pData = new CData();
            pData->x = n;
            pData->y = n * n;;

            dataList.insert(dataList.end(), pData);
      }
      
      for (i = dataList.begin(); i != dataList.end(); i++)
      {
            CData* pData = *i;
            cout << "x=" << pData->x << ", y=" << pData->y << endl;
      }

      for (i = dataList.begin(); i != dataList.end(); i++)
      {
            CData* pData = *i; // why does this fail with Access Violation on this line?
            dataList.remove(pData);
            delete pData;
      }

      return 0;
}

alfredjAsked:
Who is Participating?
 
GlennDeanConnect With a Mentor Commented:
Hi alfredj:
   You are removing an element, then trying to use the iterator to move to the next (but the iterator points to a non-existing element.
for (i = dataList.begin(); i != dataList.end(); )
{
CData* pData = *i;
i++; //move to an existing element
dataList.remove(pData);
delete pData;
}
   Glenn


0
 
jkrCommented:
Your problem seems to be the call to 'list::remove()':

"list::remove
void remove(const T& x);
The member function removes from the controlled sequence all elements, designated by the iterator P, for which *P == x."

If you want to remove a single list element, use 'list::erase()' instead, e.g.


for (i = dataList.begin(); i != dataList.end(); i++)
{
CData* pData = *i;
dataList.erase(pData);
delete pData;
}



0
 
alfredjAuthor Commented:
Okay, so I guess I do not understand the documentation.

Does remove() remove EVERYTHING IN THE LIST?  What does "removes from the controlled sequence all elements, designated by the iterator P, for which *P == x" mean (in English? German?)
Thanks, if this works, I'll happily give the points.
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
alfredjAuthor Commented:
BTW, the line...

dataList.erase(pData);

....does not compile, so I changed it to...

dataList.erase(i);

....and that compiles, but fails on the second iteration thru the loop instead of the first.

0
 
jkrCommented:
Is' schwer zu sagen, ich hätte auch erst 'alle' verstanden ;-)
0
 
jkrCommented:
Well, to be honest, I'd usually use a construct like that:

for (i = dataList.begin(); i != dataList.end(); i++)
{
delete (*i);
}

dataList.clear();
0
 
alfredjAuthor Commented:
Okay, that's cool, but I do need to
delete a single item in the list (as a result of the user's action) then write the remaining data to a database and delete the remaining items in the list (to prevent the memory leak).

0
 
alfredjAuthor Commented:
So I added a loop like this, but it fails on the second iteration.  Is it illegal to change the list when you are iterating thru it?

-Alfred


      for (i = dataList.begin(); i != dataList.end(); i++)
      {
            CData* pData = *i; // fails here on the second iteration
            if (pData->x == 4)
            {
                  cout << "DELETING: x=" << pData->x << ", y=" << pData->y << endl;
                  dataList.erase(i);
                  //delete (*i);
            }
      }
0
 
alfredjAuthor Commented:
Okay, this works.  Explain the difference between .remove() and .erase() and you get an 'A'

0
 
GlennDeanCommented:
erase deletes a particular element while remove deletes all the elements equal to a particular value.  In your case, each time you called remove it deleted one item because only 1 element had a value identical to the pointer.
   Glenn
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.