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=E9e avec new, dans cette objet, un
objet de classe A. Pour =EAtre pr=E9cis, je cr=E9e dans P une map de type
: map<int,A*>. Donc chaque A cr=E9=E9 est tout de suite class=E9 dans
cette map. Je triture tout =E7a dans tous les sens, puis quand j'ai fini
de m'amuser, je souhaite d=E9truire 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=E9truire, pour d=E9truire, j'utilise delete. Je fais une boucle :
for(int i=3D0; i=3Dtaille de la map; i++)
{
delete aMap[i];
}
et l=E0, segmentation fault. Sachant que si je compare &aMap[0] juste
apr=E8s sa cr=E9ation et juste avant sa destruction, j'obtiens la m=EAme
valeur...
Donc si vous avez une id=E9e d'o=F9 pourrait venir l'erreur, toutes vos
suggestions sera tr=E8s appr=E9ci=E9e :o)
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Michel Decima
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; }
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;
}
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; }
Cyrille
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
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
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
kanze
Michel Decima wrote:
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
Michel Decima wrote:
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
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
Michel Decima
"kanze" a écrit dans le message de news:
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.
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.
"kanze" <kanze@gabi-soft.fr> a écrit dans le message de
news:1141978397.717258.266790@i40g2000cwc.googlegroups.com...
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.
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.
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.
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.
Vincent Cantin
Donc si vous avez une idée d'où pourrait venir l'erreur, toutes vos suggestions sera très appréciée :o)
<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>
Donc si vous avez une idée d'où pourrait venir l'erreur, toutes vos
suggestions sera très appréciée :o)
<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>
Donc si vous avez une idée d'où pourrait venir l'erreur, toutes vos suggestions sera très appréciée :o)
<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>
Fabien LE LEZ
On Sat, 11 Mar 2006 11:25:07 +0800, "Vincent Cantin" :
<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.
On Sat, 11 Mar 2006 11:25:07 +0800, "Vincent Cantin"
<pere.noel@lutin.fr>:
<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.
On Sat, 11 Mar 2006 11:25:07 +0800, "Vincent Cantin" :
<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.