C'est l'addresse du pointeur qui est prise comme argument et non pas le pointeur. XD
BloodReapR
Messages postés6Date d'inscriptionvendredi 9 janvier 2009StatutMembreDernière intervention16 décembre 2009 16 déc. 2009 à 14:22
J'ai aussi un petit commentaire apropos de ton pointeur intelligent. Lorsque tu crée ton objet et affectes un pointeur, serait-il pas mieux si cela se fait dans le constructeur de la classe uniquement qui prend comme argument un pointeur vers le pointeur qui pointe sur la memoire hype? Comme ça, tu nullifie le pointeur antécédent, et en même temps tu t'assures que ton pointeur intélligent ne peut être changé par d'autres fonctions de la classe (sauf une fonction Release(); qui libère la mémoire heap prise et rend m_Ptrs = NULL;) ce qui rendra ton code plus sur. Ex:
IPointer ptrMagique(new int[BCP]);
ou sont equivalent puisque le constructeur n'est pas déclaré "explicit"
IPointer ptrMagique = new int[BCP];
Tu vois c'est avant tout savoir l'utilisation du pointeur avant de créer la classe mais puisque c'est un util d'apprentissage je te comprends fort bien. Moi pour apprendre les templates j'ai créer mon propre array dynamique (mieux connu sous le nom dans STL de std::vector) :D.
sboli
Messages postés10Date d'inscriptionvendredi 14 août 2009StatutMembreDernière intervention31 mai 2010 7 déc. 2009 à 22:57
Essayer d'implémenter un pointeur intelligent (de mauvaise facture) je ne dis pas non, mais pour une "vraie" utilisation utilise des trucs qui ont déjà fait leur preuves.
Par exemple boost.shared_ptr, boost.scoped_ptr, etc ...
snpier wolf
Messages postés216Date d'inscriptionsamedi 11 août 2007StatutMembreDernière intervention30 mai 2011 3 déc. 2009 à 11:59
ok je voi mieux le problème, je vais regarder pour empècher deux foix la même allocation merci ^^
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023123 3 déc. 2009 à 11:51
Ca fait planter le prog lors de l'appel aux destructeurs. Or chez toi, le fait de faire deux fois un "free" sur une donnée te fait une erreur silencieuse (sous Linux tu te prends un bon gros message, mais peut être pas sous Windows).
C'est une question de logique. Puisque Ptrs1 va être détruit à la fin du scope, il va libérer Y. Puis Ptrs2 va être détruit aussi, libérant de nouveau Y !
(Essaie de voir si tu peux faire: delete Block[this]; et Block[this] = 0; Libérer un pointeur null ne fait rien (et c'est tout à fait propre), ça devrait résoudre partiellement ton problème.
Pourquoi partiellement ? Parce que la chose suivante provoquera aussi toujours des erreurs:
{
int* Y= new int;
*Y = 4444;
IPointerPtrs1=Y;
{
IPointerPtrs2 =Y;
// A la fin de l'accolade, donc du scope, Ptr2s va être détruit, libérant Y
}
*Ptrs1; // Ici on déréfencera quelque chose qui a déjà été libéré (et qui est soit invalide, soit null si tu utilises ma technique précédente).
}
snpier wolf
Messages postés216Date d'inscriptionsamedi 11 août 2007StatutMembreDernière intervention30 mai 2011 3 déc. 2009 à 11:44
ok merci pour toute ces information mais j'ai une question :
int* Y= new int;
*Y = 4444;
IPointerPtrs1=Y;
IPointerPtrs2 =Y;
tu dis que sa fairai planté le prog, mais chercher moi c'est pas le cas, hazard ?
cptpingu
Messages postés3837Date d'inscriptiondimanche 12 décembre 2004StatutModérateurDernière intervention28 mars 2023123 3 déc. 2009 à 11:25
Peux-tu détailler dans ta description ce que tu appelles un pointeur intelligent, ainsi que le but de ta source ?
Ca ressemble en tout cas fortement à un std::auto_ptr (mais sans la méthode swap, et sans le changement d'appartenance en cas d'affectation) ou à un Boost::scoped_ptr.
Dans ton gros projet, avant d'utiliser cette classe, je te conseillerais de jeter un coup d'oeil à std::auto_ptr, Boost::scoped_ptr et std::shared_ptr, ça pourrait t'être utile.
Ca c'est un peu moche:
return (*Ptr.m_Ptrs==*m_Ptrs) ? 1 : 0;
Ceci fonctionne tout à fait, puisqu'une comparaison retourne une expression booléenne:
return *Ptr.m_Ptrs == *m_Ptrs;
warning: left-hand operand of comma has no effect: throw(m_Ptrs,Ptr.m_Ptrs);En effet, la virgule en C, C++ veut dire: évaluer tout les arguments, et retourner celui le plus à droite. Par exemple int a (1,2,3); veut dire a 3.
Donc c'est comme si tu écrivais: throw(Ptr.m_Ptrs);
delete Block[this];
Peut foutre la merde, en effet, tu pointes dans ton exemple sur des valeurs statiques. Donc lorsque tu essaies de les libérer, ça plante.
Il faut faire ceci pour ne pas avoir de problème:
int* Y= new int;
int* X= new int;
*Y = 4444;
*X = 1000;
Autre problème, si deux de tes pointeurs, pointent sur la même chose, alors le programme plantera à la destruction.
Ex:
int* Y= new int;
*Y = 4444;
IPointerPtrs1=Y;
IPointerPtrs2 =Y;
Plantera.
Il te faut empêcher l'affectation d'un même élément (scoped_ptr), ou en déplacer l'appartenance (auto_ptr), ou changer ta politique de destruction en ayant un compteur de référence (smart_ptr)
Plein de petits problèmes font que ta classe n'est pas encore utilisable.
23 déc. 2009 à 18:57
16 déc. 2009 à 14:30
IPointer ptrMagique(&(new int[BCP]));
IPointer ptrMagique = &(new int[BCP]);
C'est l'addresse du pointeur qui est prise comme argument et non pas le pointeur. XD
16 déc. 2009 à 14:22
IPointer::IPointer(T **ppT)
{
m_Ptrs = *pT;
*pT = 0;
}
IPointer::IPointer(const T **ppT)
{
m_Ptrs = *pT;
}
Le deuxième constructeur sera dans le cas du:
IPointer ptrMagique(new int[BCP]);
ou sont equivalent puisque le constructeur n'est pas déclaré "explicit"
IPointer ptrMagique = new int[BCP];
Tu vois c'est avant tout savoir l'utilisation du pointeur avant de créer la classe mais puisque c'est un util d'apprentissage je te comprends fort bien. Moi pour apprendre les templates j'ai créer mon propre array dynamique (mieux connu sous le nom dans STL de std::vector) :D.
7 déc. 2009 à 22:57
Par exemple boost.shared_ptr, boost.scoped_ptr, etc ...
3 déc. 2009 à 11:59
3 déc. 2009 à 11:51
C'est une question de logique. Puisque Ptrs1 va être détruit à la fin du scope, il va libérer Y. Puis Ptrs2 va être détruit aussi, libérant de nouveau Y !
(Essaie de voir si tu peux faire: delete Block[this]; et Block[this] = 0; Libérer un pointeur null ne fait rien (et c'est tout à fait propre), ça devrait résoudre partiellement ton problème.
Pourquoi partiellement ? Parce que la chose suivante provoquera aussi toujours des erreurs:
{
int* Y= new int;
*Y = 4444;
IPointerPtrs1=Y;
{
IPointerPtrs2 =Y;
// A la fin de l'accolade, donc du scope, Ptr2s va être détruit, libérant Y
}
*Ptrs1; // Ici on déréfencera quelque chose qui a déjà été libéré (et qui est soit invalide, soit null si tu utilises ma technique précédente).
}
3 déc. 2009 à 11:44
int* Y= new int;
*Y = 4444;
IPointerPtrs1=Y;
IPointerPtrs2 =Y;
tu dis que sa fairai planté le prog, mais chercher moi c'est pas le cas, hazard ?
3 déc. 2009 à 11:25
Ca ressemble en tout cas fortement à un std::auto_ptr (mais sans la méthode swap, et sans le changement d'appartenance en cas d'affectation) ou à un Boost::scoped_ptr.
Dans ton gros projet, avant d'utiliser cette classe, je te conseillerais de jeter un coup d'oeil à std::auto_ptr, Boost::scoped_ptr et std::shared_ptr, ça pourrait t'être utile.
Ca c'est un peu moche:
return (*Ptr.m_Ptrs==*m_Ptrs) ? 1 : 0;
Ceci fonctionne tout à fait, puisqu'une comparaison retourne une expression booléenne:
return *Ptr.m_Ptrs == *m_Ptrs;
warning: left-hand operand of comma has no effect: throw(m_Ptrs,Ptr.m_Ptrs);En effet, la virgule en C, C++ veut dire: évaluer tout les arguments, et retourner celui le plus à droite. Par exemple int a (1,2,3); veut dire a 3.
Donc c'est comme si tu écrivais: throw(Ptr.m_Ptrs);
delete Block[this];
Peut foutre la merde, en effet, tu pointes dans ton exemple sur des valeurs statiques. Donc lorsque tu essaies de les libérer, ça plante.
Il faut faire ceci pour ne pas avoir de problème:
int* Y= new int;
int* X= new int;
*Y = 4444;
*X = 1000;
Autre problème, si deux de tes pointeurs, pointent sur la même chose, alors le programme plantera à la destruction.
Ex:
int* Y= new int;
*Y = 4444;
IPointerPtrs1=Y;
IPointerPtrs2 =Y;
Plantera.
Il te faut empêcher l'affectation d'un même élément (scoped_ptr), ou en déplacer l'appartenance (auto_ptr), ou changer ta politique de destruction en ayant un compteur de référence (smart_ptr)
Plein de petits problèmes font que ta classe n'est pas encore utilisable.