IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[C++ natif] Implémentation d'un garbage collector


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par défaut [C++ natif] Implémentation d'un garbage collector
    Bonjour,
    voilà, je me suis fait un Garbage Collector pour une application native C++ mais j'ai un léger problème de changement d'adresse sur le pointeur this.
    L'idée de mon Garbage Collectore est d'en faire un template de classe dont tous les classes l'utilisant seront contraintes d'implémenter une interface (sans méthode) IGcObject.

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    interface IGcObject
    {
    };
     
    template<class X> class CGarbageCollector
    {
    public :
    	CGarbageCollector () 
    	{
    	};
     
    	void Purge () 
    	{
    		POSITION pos = m_ObjectListToRelease.GetHeadPosition();
    		while (pos)
    		{
    			X* elementtodelete = m_ObjectListToRelease.GetNext(pos);
    			delete elementtodelete;
    		}
    	};
     
    	~CGarbageCollector () 
    	{
    	};
     
    public :
    	void AddRef (X* inObject)
    	{
    		m_ObjectListToRelease.AddHead(inObject);
    	};
    private :
    	CList<X*, X*> m_ObjectListToRelease;
    };
     
    class UseGrab1 : public IGcObject
    {
    public :
    	explicit UseGrab1 (CGarbageCollector<IGcObject>* inGc)
    	{
    		inGc->AddRef(this);
    	};
    	virtual ~UseGrab1()
    	{
    	};
    };
    Et l'utilisation à titre d'exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    			UseGrab1* _g1_1 = new UseGrab1(&mygarbagecollector);
    			UseGrab1* _g1_2 = new UseGrab1(&mygarbagecollector);
    			UseGrab2* _g2_1 = new UseGrab2(&mygarbagecollector);
    			mygarbagecollector.Purge ();
    Le petit problème vient du passage du constructeur de mes objets _g1_1, _g1_2 et _g1_3 à la méthode AddRef() de mon Garbage Collector.
    Le problème est le suivant, je vais en debug dans le constructeur de UseGrab1, j'ai donc dans ma Call Stack :
    Je regarde l'adresse de mon pointeur this et je trouve la valeur 0x00a37F78 et dès que je passe dans la méthode AddRef de mon Garbage Collector :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	void AddRef (X* inObject)
    	{
    		m_ObjectListToRelease.AddHead(inObject);
    	};
    Je me retrouve avec l'adresse de inObject valant 0x00a37F7c.
    Et ainsi de suite pour chaque objet, mon adresse de pointeur sur l'objet courant augmente de 4 bits
    Au début, je pensais que comme étant dans mon constructeur, mon objet n'était pas encore finalisé, j'ai donc appelé la méthode AddRef depuis une autre méthode de ma classe UseGrab1, même résultat, mon adresse de pointeur this augmente de 4 bits, j'avoue que j'ai fait le tour du problème et je ne vois pas trop ce qui se passe.
    Une idée svp ?

  2. #2
    Membre éclairé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Par défaut
    Bonjour,

    je pense qu'a l'adresse 0 de ton objet se trouve son trouve son pointeur vers sa table des fonctions virtuelles (car il possède des méthodes virtuels). Après (soit 4 bits plus loin) viennent ses membres hérités, dont en premier IGcObject (même si cette classe est vide, elle débute donc à l'adresse this + 4 bits).

    Ensuite dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	explicit UseGrab1 (CGarbageCollector<IGcObject>* inGc)
    	{
    		inGc->AddRef(this);
    	};
    le fait que ce soit un template est inutile ici ; cela équivaut à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	explicit UseGrab1 (CGarbageCollector<IGcObject>* inGc)
    	{
    		inGc->AddRef<IGcObject>(this);
    	};
    donc this sera transtypé en IGcObject (soit this+4).

  3. #3
    Membre éclairé
    Avatar de gb_68
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2006
    Messages
    232
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 232
    Par défaut
    En fait ton garbage contient uniquement des IGcObject, donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	void Purge () 
    	{
    		POSITION pos = m_ObjectListToRelease.GetHeadPosition();
    		while (pos)
    		{
    			X* elementtodelete = m_ObjectListToRelease.GetNext(pos);
    			delete elementtodelete;
    		}
    	};
    équivaut à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	void Purge () 
    	{
    		POSITION pos = m_ObjectListToRelease.GetHeadPosition();
    		while (pos)
    		{
    			IGcObject * elementtodelete = m_ObjectListToRelease.GetNext(pos);
    			delete elementtodelete;
    		}
    	};
    un delete est fait sur un IGcObject (appel de son destructeur par défaut auto généré) au lieu d'être fait sur l'objet complet.

    Une solution : (voir FAQ C++ sur destructeurs)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    class IGcObject {
    virtual ~IGcObject () {};
    };

  4. #4
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par défaut
    OK, merci pour ces réponses.
    En effet, je m'étais planté dans la déclaration de template dans les objets l'utilisant.
    Par contre, un problème me vient à l'esprit car je n'avais jamais utilisé auparavant de template sur interface ou classe abstraite, est-ce possible ou bien le type d'objet sur lequel s'appuie le template doit être connu à la compil ? Il me semblerait malheureusement que oui

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    731
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 731
    Par défaut
    Bon, apparement, contrairement à java, impossible de faire des Vector<>, List<> ... à partir d'une interface commune, je suis déçu.
    Je vais me faire une classe GC dont hériteront mes autres classes, je trouve ça un peu pourri mais je vois pas d'autre solution

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Si c'est possible, seulement pour bénéficier du polymorphime il faut utiliser des références ou des pointeurs dans tes conteneurs.

Discussions similaires

  1. [JVM] Java 5 et Garbage Collector(Parralèle)
    Par ssaunois dans le forum Général Java
    Réponses: 6
    Dernier message: 28/11/2005, 23h42
  2. [JVM]Garbage collector
    Par godik dans le forum Général Java
    Réponses: 5
    Dernier message: 07/10/2005, 09h12
  3. JPanel et Garbage Collector
    Par tck-lt dans le forum Agents de placement/Fenêtres
    Réponses: 9
    Dernier message: 25/07/2005, 18h03
  4. [JVM] les objets et le Garbage collector
    Par Kurdran dans le forum Général Java
    Réponses: 7
    Dernier message: 02/06/2005, 16h57
  5. [Language]Garbage collector
    Par GETah dans le forum Langage
    Réponses: 2
    Dernier message: 23/03/2005, 15h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo