NullReferenceException

Résolu
pma3d Messages postés 36 Date d'inscription lundi 13 juin 2005 Statut Membre Dernière intervention 14 septembre 2005 - 25 août 2005 à 18:00
pma3d Messages postés 36 Date d'inscription lundi 13 juin 2005 Statut Membre Dernière intervention 14 septembre 2005 - 30 août 2005 à 17:25
Bonjour,



Je poste ici en ne sachant pas trop où mettre mon problème,
puisque même si je développe un service web, cela n'a rien à voir avec
la catégorie "service web".

Bref, j'ai donc une classe en C++ managé qui encapsule une classe non
managée. La classe managée contient simplement un pointeur vers la
classe non managée :

public __gc class ClasseManagee: public IDisposable


{


public:


// Constructeur


ClasseManagee(void){


m_pThis = new ClasseNonManagee();


}



// Destructeur


~ClasseManagee(void){


delete m_pThis;


// Dispose();


}


protected:


ClasseNonManagee__nogc* m_pThis;


};


Lorsque je lance ceci, j'obtiens une exception NullReferenceException
sur le delete m_pThis. Le problème est que j'ai vérifié en mode debug,
tous mon pointeur est pourtant bien référencé à cet endroit !!! Ca fait
des jours que je recherche des infos, mais je ne trouve rien, alors
j'espère que quelqu'un aura déjà eu ce cas et pourra m'aider à m'en
sortir.

Merci d'avance !

6 réponses

pma3d Messages postés 36 Date d'inscription lundi 13 juin 2005 Statut Membre Dernière intervention 14 septembre 2005
30 août 2005 à 17:25
Bon, en fait, j'ai trouvé d'où venait le problème, après quelques jours
de traque, comme vous pouvez le voir à la date de ce post

Donc, ça venait de plus haut, dans mon client web. J'avais un peu trop
simplifié le code donné en exemple en haut, l'erreur venait d'un
constructeur supplémentaire, qui me permettait d'initialiser
directement la valeur du pointeur avec une adresse récupérée
auparavant. A l'époque, je ne pensais pas que ça pouvait venir de là.
J'étais focalisé sur le Garbage Collector dont on ne peut pas maîtriser
le fonctionnement, et là était mon erreur.

Le problème est que plusieurs instances de ClasseManagee étaient
créées, et un certain nombre d'entre elles pointaient vers la même zone
non managée. Une fois la première instance de ClasseManagee libérée, et
donc le pointeur m_pThis allant avec, l'instance suivante avec le même
pointeur ne pouvait pas le libérer. Ceci explique aussi pourquoi le
pointeur contenait bien une valeur, mais la case mémoire pointée avait
déjà été libérée !!! Il m'a suffit de faire en sorte qu'une seule
instance de ClasseManagee soit créée pour une valeur de m_pThis, et le
tour était joué !
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
25 août 2005 à 18:29
Salut, bien que le __nogc* soit implicite, as tu éssayé sans: ( ClassNonManagee* m_pThis ) ?
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
25 août 2005 à 19:11
Peut être Dispose qui passe avant le destructeur ? En MC++ je sais pas trop mais normalement tu devrais deleter le pointeur dans Dispose et le destructeur devrait appeler Dispose, utilises GC.SuppressFinalize dans Dispose.
0
pma3d Messages postés 36 Date d'inscription lundi 13 juin 2005 Statut Membre Dernière intervention 14 septembre 2005
25 août 2005 à 21:01
Alors, pour le nogc, effectivement, il est implicite, et par
conséquent, sa présence ou son absence n'ont absolument aucun effet. Il
est là juste pour la clarté.

Pour le Dispose, en fait, il est en commentaire, c'est un reste que j'avais utilisé suite aux instructions données sur la msdn.

J'ai essayé de faire exactement comme ils le disent, c'est-à-dire,
comme tu le précises, de mettre le delete dans la méthode Dispose, ce
qui apparemment permettrait de laisser décider au Garbage collector du
moment adéquat pour l'effectuer. La solution proposée ne marche pas
(d'ailleurs, je ne serais pas là dans le cas contraire )...

Mais, là où tu m'intéresses, c'est avec la méthode SuppressFinalize().
En effet, j'ai déjà essayé à tout hasard de l'utiliser pour empêcher le
GC de finaliser ma classe managée, et donc, si j'ai bien, d'appeler le
destructeur, mais ça ne marchait pas non plus. Que veux-tu dire par
utiliser SuppressFinalize dans Dispose? Tu veux dire sur mon pointeur
non managé ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
26 août 2005 à 00:18
C'est exactement comme ca que Microsoft propose de "wrapper" une classe non managée, donc je ne sais pas désolé. Pour ce qui est de la méthode Dispose et SuppressFinalize le meilleur moyen de l'implementer de manière robuste c'est de respecter ce modèle:

http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/cpref/html/frlrfSystemIDisposableClassDisposeTopic.asp
0
pma3d Messages postés 36 Date d'inscription lundi 13 juin 2005 Statut Membre Dernière intervention 14 septembre 2005
26 août 2005 à 10:18
Merci pour le lien, je n'avais pas pensé à chercher des infos sur la
méthode dispose, et c'est effectivement intéressant. En fait, le lien
dont je te parlais était celui ci :

http://msdn.microsoft.com/library/fre/default.asp?url=/library/FRE/vcmex/html/vcgrfmanagedwrappersaroundunmanagedtypes.asp

sur lequel ils ne parlent bizarrement pas du SuppressFinalize().

J'ai donc essayé en suivant la méthode donnée sur ton lien, et ça ne
change rien. Une fois arrivé sur le delete, j'obtiens l'exception.

Cependant, j'ai peut-être trouvé d'autres pistes, alors je vais tenter de les suivre.

Merci pour le temps passé sur mon cas lutinore
0
Rejoignez-nous