Sergiu
February 17, 2009, 1:28pm
1
I have created a list of class objects.The question is, why doesn’t the following code delete the list items when the condition is fufilled.
The code:
…
list<racheta*> listaRachete;
list<racheta*>::iterator iterIntList;
…
switch(key)
{
case 32 :
racheta *a=new racheta;
listaRachete.push_front(a);
break;
}
…
…
for(iterIntList=listaRachete.begin();iterIntList!=listaRachete.end();iterIntList++) {
if ((*iterIntList)->dead==1) delete *iterIntList;
else
(*iterIntList)->mutaRacheta();}
…
The following line of code is dangerous :
if ((*iterIntList)->dead==1) delete *iterIntList;
You delete the memory of the pointer in the STL list but the pointer is still in the list.
I think you can do something like this
for(iterIntList=listaRachete.begin();iterIntList!=listaRachete.end();iterIntList++) {
if ((*iterIntList)->dead==1)
{
delete *iterIntList;
listaRachete.erase(iterIntList);
}
else
{
(*iterIntList)->mutaRacheta();}
}
I have not tested so I hope that it will not segfault.
Sergiu
February 18, 2009, 12:23am
3
The code doesn’t work.Thank you for trying altought.
As previously mentioned you deleted the object that is still within the list. One suggestion, take a look at the boost library and it’s smart pointer(like shared_ptr). shared_ptr deletes the object for you when reference count drops to 0. Then you can do
typedef boost::shared_ptr<racheta> pracheta;
std::list<pracheta> listaRachete;
...
listaRachete.push_front(pracheta(new racheta));
...
As for deleting object from list. A proper way of doing this would be like this:
...
class ErasePred
{
public:
bool operator()(prachete r) const
{
if (r->dead == 1)
{
return true;
}
else
{
return false;
}
}
};
...
// remove all elements for which
// ErasePred::operator() returns true
std::remove_if(listaRachete.begin(),
listaRachete.end(),
ErasePred());
…of the top of my head.
Sergiu
February 18, 2009, 2:49am
5
There seems to be an error with the declaration of class ErasePred…
The problem with my code is after this instruction listaRachete.erase(iterIntList); I cannot use the iterIntList iterator anymore to advance in the list.
The following use 2 iterators:
list<racheta*>::iterator iterIntList;
list<racheta*>::iterator deleteIntList;
iterIntList = iterIntList=listaRachete.begin();
while(iterIntList!=listaRachete.end())
{
if ((*iterIntList)->dead==1)
{
deleteIntList = iterIntList;
iterIntList++;
delete *deleteIntList;
listaRachete.erase(deleteIntList);
}
else
{
(*iterIntList)->mutaRacheta();}
iterIntList++;
}
}
I have tested that and it work.
Sergiu
February 18, 2009, 8:03am
7
Thank you very much for the help.You helped allot.