POINTEUR INTELLIGENT

cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 - 3 déc. 2009 à 11:25
abdousmi Messages postés 2 Date d'inscription jeudi 10 décembre 2009 Statut Membre Dernière intervention 30 mai 2012 - 23 déc. 2009 à 18:57
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/50928-pointeur-intelligent

abdousmi Messages postés 2 Date d'inscription jeudi 10 décembre 2009 Statut Membre Dernière intervention 30 mai 2012
23 déc. 2009 à 18:57
j ai trouver une erreur je ss pas ou ?
BloodReapR Messages postés 6 Date d'inscription vendredi 9 janvier 2009 Statut Membre Dernière intervention 16 décembre 2009
16 déc. 2009 à 14:30
Désoler, une erreur de syntaxe de ma part:

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
BloodReapR Messages postés 6 Date d'inscription vendredi 9 janvier 2009 Statut Membre Dernière intervention 16 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::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.
sboli Messages postés 10 Date d'inscription vendredi 14 août 2009 Statut Membre Dernière intervention 31 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és 216 Date d'inscription samedi 11 août 2007 Statut Membre Dernière intervention 30 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és 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
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és 216 Date d'inscription samedi 11 août 2007 Statut Membre Dernière intervention 30 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és 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
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.
Rejoignez-nous