OVH Cloud OVH Cloud

[Mem leaks] Gestion memoire avec vecteur de pointeurs

2 réponses
Avatar
AD
Bonjour,

J'ai réalisé une implémentation de l'algo A* en C++, comme certains le
savent, cet algo génère une qté exponentielle d'états.

J'ai donc une classe CEtat et chaque objet de cette classe possède un
vecteur de pointeurs sur d'autres CEtat. (voir m_enfants)

Je désire à la fin de l'execution de l'algo réaliser un nettoyage
mémoire correct. J'ai essayé d'ajouter une methode clear() qui appelle
cette meme methode sur chaque element du vecteur m_enfants. jusqu'au
dernier que l'on delete...
Mais ça n'a rien changé, l'algo explose en mémoire.
Merci davance pour vos remarques !

Alex.
______________________________________________________________
class CEtat : public CEtatAbstraite
{
public:
void clear(void);
CEtat* getParent(void);
vector <CEtat*> getEnfants(void);

int ajouterParent(CEtat* parent);
int ajouterEnfant(CEtat* enfant);

// Constructeur par defaut
CEtat();

// Constructeur g h et point
CEtat(Ttemps g, Ttemps h, CCoord point);
virtual ~CEtat();

/* Acces */
int setF(void);
int setG(Ttemps val);
int setH(Ttemps val);
Ttemps getF(void);
Ttemps getH(void);
Ttemps getG();

/* accesseurs sur le point */
CCoord getPoint(void);
int setPoint(double x, double y);

private:
Ttemps m_g;
Ttemps m_h;
CCoord m_point;

CEtat* m_parent;
vector <CEtat*> m_enfants;

};
__________________________________________________________________

void CEtat::clear()
{
vector<CEtat*>::iterator pos;
CEtat * tmp;

if( m_enfants.size() > 0 )
{
for( pos=m_enfants.begin(); pos!=m_enfants.end(); ++pos)
{
tmp = *pos;
tmp->clear();
}

while( m_enfants.size() > 0)
{
tmp = m_enfants.back();
try
{
delete( tmp );
m_enfants.pop_back();
}
catch( ... )
{
tmp->clear();
m_enfants.pop_back();
}

}
}
else
{
m_enfants.clear();
}

}
________________________________________________________

2 réponses

Avatar
Christophe Lephay
AD wrote:
void CEtat::clear()
{
vector<CEtat*>::iterator pos;
CEtat * tmp;

if( m_enfants.size() > 0 )


Ce test me semble superflu...

{
for( pos=m_enfants.begin(); pos!=m_enfants.end(); ++pos)
{
tmp = *pos;
tmp->clear();


Pourquoi ne pas faire le delete tmp; à cet endroit ?

}

while( m_enfants.size() > 0)
{
tmp = m_enfants.back();
try
{
delete( tmp );
m_enfants.pop_back();


Ce code ne devrait pas lancer d'exceptions, alors pourquoi le try... ?

}
catch( ... )
{
tmp->clear();
m_enfants.pop_back();
}

}
}
else


A quoi correspond ce else ? Si c'est au if( m_enfants.size() > 0 ), il est
superflu, le vector étant déjà vide...

{
m_enfants.clear();
}

}


A priori je ne vois pas de sources de fuite dans ton algo. Cependant :

1- Je le trouve un peu confus (ce qui est à éviter particulièrement dans les
algos récursifs)
2- Je ne comprends pas pourquoi tu n'effectues pas tout ton travail de
libération des enfants dans le destructeur de ta classe. L'algo en serait
d'autant plus clair. Il est d'ailleurs bien possible que tes fuites vienne
d'un endroit où tu effaces des états sans appeler clear au préalable. Ce
serait bien que tu montres aussi le code de ton destructeur...

Chris

Avatar
AD
Christophe Lephay wrote:
AD wrote:

void CEtat::clear()
{
vector<CEtat*>::iterator pos;
CEtat * tmp;

if( m_enfants.size() > 0 )



Ce test me semble superflu...


{
for( pos=m_enfants.begin(); pos!=m_enfants.end(); ++pos)
{
tmp = *pos;
tmp->clear();



Pourquoi ne pas faire le delete tmp; à cet endroit ?


C'est ce que j'ai fait au début. L'algo était beaucoup plus simple au
début, mais plantait sur le delete.



}

while( m_enfants.size() > 0)
{
tmp = m_enfants.back();
try
{
delete( tmp );
m_enfants.pop_back();



Ce code ne devrait pas lancer d'exceptions, alors pourquoi le try... ?
voilà le prob j'ai ajouté le try car je n'arrive pas à faire le delete

pour tous les pointeurs ! C'est vrai que ça ne règle pas le problème
mais je ne comprends pas pourquoi le delete foire sur certains elements
du vecteur.


}
catch( ... )
{
tmp->clear();
m_enfants.pop_back();
}

}
}
else



A quoi correspond ce else ? Si c'est au if( m_enfants.size() > 0 ), il est
superflu, le vector étant déjà vide...


oui, à force de faire des modifs, on arrive à n'importe quoi :)



{
m_enfants.clear();
}

}



A priori je ne vois pas de sources de fuite dans ton algo. Cependant :

1- Je le trouve un peu confus (ce qui est à éviter particulièrement dans les
algos récursifs)
je te l'accorde.

2- Je ne comprends pas pourquoi tu n'effectues pas tout ton travail de
libération des enfants dans le destructeur de ta classe. L'algo en serait
d'autant plus clair. Il est d'ailleurs bien possible que tes fuites vienne
d'un endroit où tu effaces des états sans appeler clear au préalable. Ce
serait bien que tu montres aussi le code de ton destructeur...
En fait à la base je pensais tout faire dans le destructeur, mais je

vois pas trop pourquoi l'algo serait plus clair, je suis bien obligé
dans tous les cas de faire un delete pour chaque élément de mon vecteur,
non ?


Chris




En tout cas merci de ta réponse, je vais retenter par le destructeur.
Alex.