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 :

Memory Managment, Smart Ptr et exemple concret :


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut Memory Managment, Smart Ptr et exemple concret :
    Bonjour à tous .

    Tout d'abbord une question d'ordre général, je cherche à gérer les problème de mémoire qui peuvent survenir dans une application, pour cela j'ai vu globalement 2 méthodes :

    - surcharge des new / delete [ j'ai du mal a totu assimilé à ce niveau ... et j'ai du mal à mettre vraiment le nez dedans ]
    - création d'un classe mère avec un conteneur static de tou les objets, le tout agrémenter de smart ptr .

    Je me demande si je ne peux pas m'en sortir, uniquement a l'aide de smart ptr , de cette facons, plus de problème avec les new/delete, et le reste du code ne doit normalment pas posé de problème, la destruction des objet étant automatique ... je me trompe ?

    J'attend vos conseils

    Sinon, je commence à peine à manipuler les smart ptr , et j'essaie de me faire la main dessus, et je me heurte à un petit problème : je veux implémenter une version simple ( dans le simple but de tester ) d'une manager de texture .

    Celui-ci possède une simple fonction Get(), qui va :
    - charge la texture associé à l'ID passé en argument si ce n'est déja fait
    - retourner un pointeur vers la texture quoi qu'il arrive

    Ca marche, pas de problème, et mes texture sont détruite automatiquement quand on TextureManager est détruit .

    Le problème est qu'il manque une foncitonalité que je n'arrive pas à coder :

    Quand tout les objets utilisant une texture donné sont détruit, la texture doit être détruite , hors dans mon code ce n'est pas possible, car je stocke mes texture dans une map qui associe un entier, avec un smart ptr vers la texture, donc quoi qu'il arrive , jusqu'à la mort de mon manager, il restera un smart ptr qui pointera vers chaqu'une de mes textures :

    voila le code minimal qui reproduit ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class CItem
    {
    public :
    	boost::shared_ptr<CTexture> T ;
    };
    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
    class CTexture
    {
    public :
    	CTexture(int ID_t)
    	{
    		ID = ID_t ;
    		std::cout << "Texture " << ID << " is created" << std::endl ;
    	}
    	~CTexture()
    	{
    		std::cout << "Texture " << ID << " is destroyed" << std::endl ;
    	}
    private :
    	int ID ;
    };
    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
    #include <vector>
    #include <map>
     
    class CTextureManager
    {
    public:
    	boost::shared_ptr<CTexture> Get(int ID)
    	{
    		if ( Map_Texture.find(ID) == Map_Texture.end() )
    		{
    			Map_Texture[ID] = boost::shared_ptr<CTexture>( new CTexture(ID)) ;
    		}
    		return Map_Texture[ID] ;
    	}
    private :
    	std::map <int, boost::shared_ptr<CTexture> > Map_Texture ;
    };

    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
    int main(int argc, char *argv[])
    {
    	SDL_Init(0);
    	CTextureManager M ;
     
    	CItem I;
    	{
    	CItem I1,I2 ;
     
    	I.T = M.Get(0);
    	I1.T = M.Get(1);
    	I2.T = M.Get(1) ;
    	}
    	std::cout << " ------------------------ " << std::endl ;
     
     
    	SDL_Quit();
     
    	return 0;
    }
    Le fichier output :

    Texture 0 is created
    Texture 1 is created
    ------------------------
    Texture 1 is destroyed
    Texture 0 is destroyed
    J'aimerai que la texture 1 soit détruite juste après l'acolade fermente ( donc aprés le "----" dans l'output ) .

    Merci .

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Il suffit que ton gestionnaire de texture n'incrémente pas le compteur de référence des textures qu'il stocke. Ca doit pouvoir se faire avec boost, mais je ne connais pas les détails.

    Mais en général on veut garder ce comportement, pour éviter qu'une texture inutilisée ne soit déchargée immédiatement. Disons que c'est encore mieux si c'est toi qui gère la destruction des textures, plutôt que les pointeurs intelligents.

  3. #3
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Effectivement, il y a un truc, je l'indique dans mon tuto sur Boost.SmaprtPtr, c'est la classe weak_ptr<> qui n'incrémente pas le compteur de références. Mais attention, comme le dit Laurent, dès qu'une référence est détruite, la mémoire est désallouée, ce qui fait que le weak_ptr<> est invalidé et donc ne peut plus se transformer en shared_ptr<>, il faut donc détecter ce cas, mais je ne sais pas quelle est la réponse dans le cas où on vient de créer la bête -> quand tu crées ton weak_ptr<>, retourne directement un shared_ptr<> grâce à la fonction lock(), et la condition sera aussi un test de validité du pointeur trouvé.

  4. #4
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut
    Mais en général on veut garder ce comportement, pour éviter qu'une texture inutilisée ne soit déchargée immédiatement. Disons que c'est encore mieux si c'est toi qui gère la destruction des textures, plutôt que les pointeurs intelligents.
    Je pense au final gérer mes textures ( et mes objets en général ) de différentes manière, en distinguant ceux dont on peux se séparé dés qu'il ne sont plus utilisé, ceux qu'on peut supprimer a un moment donné et ceux que l'on peux gardé jusqua la fin de vie du Manager de ressources .

    Ma première version du code illustre le comportement numéro 3 .

    Je cherche donc a simulé le comportement numéro 1 dans un premier temps.

    Je viens de tester, en utilisant des weak_ptr dans ma "map" et en retournant "Map_Texture[ID].lock()" dans ma fonction get(), mais il semble que les texture soit créer / détruite aussitot ... Je vais voir comment contourner cela .

    EDIT : Je ne connais vraiment pas weak_ptr, alors je vais faire un peu de lecture pour voir son fonctionnement au lieu de tatonner comme un manchot

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Février 2006
    Messages
    943
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Finance

    Informations forums :
    Inscription : Février 2006
    Messages : 943
    Par défaut
    En effet, je ferais un gestionnaire qui ne detruit pas automatiquement les textures car sinon tu va te retrouver a faire des chargements et des dechargements a chaque fois ce qui reduit l'interet du gestionnaire.

    Dans ce cas tu as plusieurs possibilité :
    - charger tes objets au debut (pour de petits projets c'est impec) et smart pointers tues tout a la fin.
    - charger dinamiquement et mettre en dur dans ton programme ce qu'il faut eleminer.

    Pour la redefinition de new/delete/new[]/delete[] c'est un autre but.
    Tu peux avoir besoin de faire des classes de bases que tu veux fiables/rapides/compactes dans ce cas tu veux pas gerer de compteurs, meme leger. Tu declare tes surcharges en mode debug et ainsi tu es sur d'avoir quelque chose de correcte. Ensuite tu enleves la surcharge.

    En tout cas les deux rendent de grands services

  6. #6
    Membre éclairé
    Inscrit en
    Octobre 2004
    Messages
    616
    Détails du profil
    Informations forums :
    Inscription : Octobre 2004
    Messages : 616
    Par défaut
    En effet, je ferais un gestionnaire qui ne detruit pas automatiquement les textures car sinon tu va te retrouver a faire des chargements et des dechargements a chaque fois ce qui reduit l'interet du gestionnaire.

    Dans ce cas tu as plusieurs possibilité :
    - charger tes objets au debut (pour de petits projets c'est impec) et smart pointers tues tout a la fin.
    - charger dinamiquement et mettre en dur dans ton programme ce qu'il faut eleminer.
    Tout à fait d'accord Ca recoupe d'ailleur mon message précédent

    Pour la redefinition de new/delete/new[]/delete[] c'est un autre but.
    Ma fois ... ca ne peux que me faire du bien de mettre le nez plus en pronfondeur dans tout ca, ca m'aidera à combler des lacunes également ! Dés que j'ai le temps .... c'est en projet !


    Concernant les weak_ptr, je viens de voir quelques exemples, et j'ai comprit pourquoi mes textures étaient créer / détruite instantanément .

    En effet, je cré le weak_ptr AVANT que mon objet ai acquis un shared_ptr ... donc forcément le weak_ptr part en fumé ... je vais chercher comment régler le problème !

    ( pour info , le code correcpondant avec un ouput )
    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
    class CTextureManager
    {
    public:
    	boost::shared_ptr<CTexture> Get(int ID)
    	{
    		if ( Map_Texture.find(ID) == Map_Texture.end() )
    		{
    			Map_Texture[ID] = boost::shared_ptr<CTexture>( new CTexture(ID)) ;
    		}
    		if ( ! Map_Texture[ID].lock())
    			std::cout << " [ Erreur ] " << std::endl ;
     
    		return Map_Texture[ID].lock() ;
    	}
    private :
    	std::map <int, boost::weak_ptr<CTexture> > Map_Texture ;
    };

    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
    int main(int argc, char *argv[])
    {
    	SDL_Init(0);
    	CTextureManager M ;
     
    	CItem I;
    	{
    	CItem I1,I2 ;
     
    	I.T = M.Get(0);
    	I1.T = M.Get(1);
    	I2.T = M.Get(1) ;
    	}
    	std::cout << " ------------------------ " << std::endl ;
     
     
    	SDL_Quit();
     
    	return 0;
    }
    Texture 0 is created
    Texture 0 is destroyed
    [ Erreur ]
    Texture 1 is created
    Texture 1 is destroyed
    [ Erreur ]
    [ Erreur ]
    ------------------------

  7. #7
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Pourquoi tu fais un shared_ptr<> tout de suite et pas un weak_ptr<> ?

Discussions similaires

  1. Réponses: 10
    Dernier message: 29/03/2009, 16h24
  2. Exemple concret de jointures
    Par Lenezir dans le forum Langage SQL
    Réponses: 2
    Dernier message: 01/02/2008, 16h56
  3. Memory Managment dans vos programmes
    Par Clad3 dans le forum C++
    Réponses: 11
    Dernier message: 25/07/2006, 01h25
  4. heap memory manager
    Par flames dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 02/06/2006, 12h17

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