 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Guest
|
Posted: Thu Mar 09, 2006 2:06 pm Post subject: raisons d'une erreur avec delete? |
|
|
Bonjour,
j'ai un probleme d'utilisation de delete avec un objet map. Mon code
est peu trop gros, donc je vais essayer de vous expliquer clairement la
situation :
J'ai un objet que j'appelle P. Je crée avec new, dans cette objet, un
objet de classe A. Pour être précis, je crée dans P une map de type
: map<int,A*>. Donc chaque A créé est tout de suite classé dans
cette map. Je triture tout ça dans tous les sens, puis quand j'ai fini
de m'amuser, je souhaite détruire le tout.
donc je fais mon delete P; qui appelle le destructeur de A. Jusqu'ici
tout va bien.
Soit : map<int,A*> aMap; la map contenant les A que je souhaite
détruire, pour détruire, j'utilise delete. Je fais une boucle :
for(int i=0; i=taille de la map; i++)
{
delete aMap[i];
}
et là, segmentation fault. Sachant que si je compare &aMap[0] juste
après sa création et juste avant sa destruction, j'obtiens la même
valeur...
Donc si vous avez une idée d'où pourrait venir l'erreur, toutes vos
suggestions sera très appréciée ) |
|
| Back to top |
|
 |
Cyrille Guest
|
Posted: Thu Mar 09, 2006 3:06 pm Post subject: Re: raisons d'une erreur avec delete? |
|
|
olivier.faust (AT) gmail (DOT) com a écrit :
| Quote: | Bonjour,
j'ai un probleme d'utilisation de delete avec un objet map. Mon code
est peu trop gros, donc je vais essayer de vous expliquer clairement la
situation :
J'ai un objet que j'appelle P. Je crée avec new, dans cette objet, un
objet de classe A. Pour être précis, je crée dans P une map de type
: map<int,A*>. Donc chaque A créé est tout de suite classé dans
cette map. Je triture tout ça dans tous les sens, puis quand j'ai fini
de m'amuser, je souhaite détruire le tout.
donc je fais mon delete P; qui appelle le destructeur de A. Jusqu'ici
tout va bien.
Soit : map<int,A*> aMap; la map contenant les A que je souhaite
détruire, pour détruire, j'utilise delete. Je fais une boucle :
for(int i=0; i=taille de la map; i++)
{
delete aMap[i];
}
|
Là, il faut que tous les entiers de 0 à "taille de la map" soient
présents dans votre map. Si ce n'est pas le cas, vous aurez des 'i' pour
lesquels aMap[i] ne correspondra pas à quelque chose que vous avez
alloué, donc vous ferez probablement un delete sur une zone-mémoire qui
ne vous appartient pas ou qui n'existe pas et donc ça fera kaboum.
Je vous propose plutôt de parcourir votre map ainsi:
for ( map<int, A*::iterator it = aMap.begin(); it != aMap.end(); ++it )
{
delete it->second;
}
Comme ça vous enlèverez seulement ce qui est présent dans la map.
Autre possibilité, qui évite de faire une boucle de delete, utiliser
boost::shared_ptr<>:
map<int, boost::shared_ptr<A> > aMap;
Ainsi il suffit d'utiliser aMap::clear() pour détruire tous les
boost::shared_ptr<A> qui, dans leur destructeur, s'occuperont de faire
chacun un delete sur l'objet A sur lequel ils pointent respectivement.
--
"Kill Them All!" ~ Mohandas Karamchand "Mahatma" Gandhi |
|
| Back to top |
|
 |
Michel Decima Guest
|
Posted: Thu Mar 09, 2006 3:06 pm Post subject: Re: raisons d'une erreur avec delete? |
|
|
| Quote: | Soit : map<int,A*> aMap; la map contenant les A que je souhaite
détruire, pour détruire, j'utilise delete. Je fais une boucle :
for(int i=0; i=taille de la map; i++)
{
delete aMap[i];
}
|
Ne serait il pas plus judicieux d'utiliser des iterateurs pour la boucle ?
map<int,A*>::iterator it_end = aMap.end();
for (map<int,A*>::iterator it = aMap.begin(); it != it_end; ++it)
{
delete it->second;
} |
|
| Back to top |
|
 |
Michel Decima Guest
|
Posted: Fri Mar 10, 2006 9:06 am Post subject: Re: raisons d'une erreur avec delete? |
|
|
"kanze" <kanze@gabi-soft.fr> a écrit dans le message de
news:1141978397.717258.266790 (AT) i40g2000cwc (DOT) googlegroups.com...
| Quote: | map<int,A*>::iterator it_end = aMap.end();
for (map<int,A*>::iterator it = aMap.begin(); it != it_end; ++it)
{
delete it->second;
}
Juste un point de détail, mais formellement, ça donne un
comportement indéfini -- après le delete, le pointeur n'est
(officiellement, en tout cas) plus copiable, ce qui viole les
contraits des collections.
|
Je ne savais pas qu'un pointeur n'est plus copiable apres delete.
| Quote: | Dans la pratique, évidemment, ça ne donnerait jamais de
problèmes. Mais pour être 100% conforme, il faudrait quelque
chose comme :
template< typename T
struct Deleter
{
void operator()( T*& p ) const
{
T* tmp = p ;
p = NULL ;
delete tmp ;
}
} ;
avec ensuite :
std::for_each( aMap.begin(), aMap.end(), Deleter< A >() ) ;
|
Pour des container associatifs, ca ne va pas marcher directement,
mais je vois l'idee. |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Mar 10, 2006 9:06 am Post subject: Re: raisons d'une erreur avec delete? |
|
|
Michel Decima wrote:
| Quote: | Soit : map<int,A*> aMap; la map contenant les A que je souhaite
détruire, pour détruire, j'utilise delete. Je fais une boucle :
for(int i=0; i=taille de la map; i++)
{
delete aMap[i];
}
Ne serait il pas plus judicieux d'utiliser des iterateurs pour
la boucle ?
map<int,A*>::iterator it_end = aMap.end();
for (map<int,A*>::iterator it = aMap.begin(); it != it_end; ++it)
{
delete it->second;
}
|
Juste un point de détail, mais formellement, ça donne un
comportement indéfini -- après le delete, le pointeur n'est
(officiellement, en tout cas) plus copiable, ce qui viole les
contraits des collections.
Dans la pratique, évidemment, ça ne donnerait jamais de
problèmes. Mais pour être 100% conforme, il faudrait quelque
chose comme :
template< typename T >
struct Deleter
{
void operator()( T*& p ) const
{
T* tmp = p ;
p = NULL ;
delete tmp ;
}
} ;
avec ensuite :
std::for_each( aMap.begin(), aMap.end(), Deleter< A >() ) ;
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34 |
|
| Back to top |
|
 |
Vincent Cantin Guest
|
Posted: Sat Mar 11, 2006 4:06 am Post subject: Re: raisons d'une erreur avec delete? |
|
|
Donc si vous avez une idée d'où pourrait venir l'erreur, toutes vos
suggestions sera très appréciée )
<Troll>L'erreur vient du choix de la lib (et du language). J'ai jamais de
problemes comme ca avec Java.</Troll>
<Serieusement>Peut-etre que quelque part tu delete 2 fois sur tes pointeurs,
donc la deuxieme fois il ne comprend pas ce que tu fais et BOUM ..
casse.</Serieusement> |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Sat Mar 11, 2006 5:06 am Post subject: Re: raisons d'une erreur avec delete? |
|
|
On Sat, 11 Mar 2006 11:25:07 +0800, "Vincent Cantin"
<pere.noel (AT) lutin (DOT) fr>:
| Quote: | Troll>L'erreur vient du choix de la lib (et du language). J'ai jamais de
problemes comme ca avec Java.</Troll
|
La différence n'est pas tellement due au langage, mais à la présence
d'un garbage collector. Il n'y en a pas par défaut en C++, mais on
peut en mettre un si on fait beaucoup d'allocations dynamiques. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|