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 :

Garder en mémoire un object TBitmap


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Points : 46
    Points
    46
    Par défaut Garder en mémoire un object TBitmap
    Bonjour à tous,


    J'utilise pour mon projet une grille (TStringGrid) dans laquelle j'insère des petits icônes au format bitmap en utilisant l'événement OnDrawCell(), jusqu'ici pas de problème.

    Pour l'instant, OnDrawCell me sert à charger et à dessiner les Bitmaps:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    void __fastcall TForm_Main::StringGridDrawCell(TObject *Sender, int ACol,
    	  int ARow, TRect &Rect, TGridDrawState State)
    {
         Graphics::TBitmap *Icone = new Graphics::TBitmap;
         Icone->LoadFromFile(Images//IconeRouge.bmp);
     
    // fonction me permettant de dessiner l'icône à l'endroit désiré et fond tranparent.
         DrawTransparentBitmap(StringGrid->Canvas,Icone,0x00ff0000,Rect.Left+5,Rect.Top+17);
         delete Icone;
    }
    Pour des raisons d'optimisation, j'aimerais ne plus devoir charger ces Bitmaps à chaque évenements OnDrawCell, mais seulement le faire à l'initialisation.

    .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class TForm_Main : public TForm
    {
        public:
        Graphics::TBitmap *m_Icone;
    }
    .cpp
    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
     
    void TForm_Main::initMainForm()
    {
         Graphics::TBitmap *m_Icone = new Graphics::TBitmap;
         m_Icone->LoadFromFile(Images//IconeRouge.bmp);
    }
     
    void __fastcall TForm_Main::StringGridDrawCell(TObject *Sender, int ACol,
    	  int ARow, TRect &Rect, TGridDrawState State)
    {
         Graphics::TBitmap *IconeTest = new Graphics::TBitmap;
         IconeTest = m_Icone;
         DrawTransparentBitmap(StringGrid->Canvas,IconeTest,0x00ff0000,Rect.Left+5,Rect.Top+17);
         delete IconeTest;
    }
    Malheureusement, dès que je quitte la fonction d'initialisation, m_Icone devient NULL, pourtant je ne la supprime pas, où est mon erreur?


    Bonne journée!

    Frédéric

  2. #2
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Es tu obligé de mettre ton attribut en public?
    tu ne sais pas ce qu'il peu lui arriver....


    ensuite il doit y avoir un constructeur par copie pour la classe Graphics::TBitmap.


    les explications de tes soucis dans els commentaires.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    // tu alloue un nouvel objet.
    Graphics::TBitmap *IconeTest = new Graphics::TBitmap(); 
    // tu perd la référence a cet objet en lui donnant celle d'un autre (m_Icone).
    // en perdant cette reference tu crée un fuite mémoire.
    IconeTest = m_Icone;  
     
    ...
    // tu efface l'obet referencé par m_Icone 
    // car IconeTest pointe sur la même zone mémoire.
    delete IconeTest;
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Points : 46
    Points
    46
    Par défaut
    Salut jabbounet!


    C'est vrai que je ne suis pas obligé de la mettre en public, mais je ne pense pas que mon problème vienne de cela.

    ensuite il doit y avoir un constructeur par copie pour la classe Graphics::TBitmap.
    Je ne comprends pas bien ta phrase, j'initialise pourtant bien les deux objets Icone et IconeTest, l'un dans la fonction initMainForm() et l'autre dans l'événement OnDrawCell. La portée de IconeTest est limitée à l'événement, donc je le détruis à la fin de OnDrawCell tandis que l'objet Icone fait partie de la form, je le détruis donc dans le destructeur de celle-ci, ça me semble correct mais je peux me tromper.

    Par contre, je n'avais pas pensé au fait que si je donne la référence de Icone à IconeTest et que je détruis IconeTest, alors Icone est aussi détruit? Comment faire pour détruire IconeTest sans détruire Icone?

    D'un autre côté, lorsque j'entre dans l'événement OnDrawCell, Icone est déjà nul, donc mon souci vient d'autre chose (même si le problème que tu soulèves existe)


    Frédéric

  4. #4
    Membre expert Avatar de jabbounet
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juin 2009
    Messages
    1 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Juin 2009
    Messages : 1 909
    Points : 3 284
    Points
    3 284
    Par défaut
    Citation Envoyé par FredLo Voir le message
    Salut jabbounet!


    C'est vrai que je ne suis pas obligé de la mettre en public, mais je ne pense pas que mon problème vienne de cela.
    non mais un autre objet pourrait aller s'amuser a trifouiller dedans...



    Je ne comprends pas bien ta phrase, j'initialise pourtant bien les deux objets Icone et IconeTest, l'un dans la fonction initMainForm() et l'autre dans l'événement OnDrawCell. La portée de IconeTest est limitée à l'événement, donc je le détruis à la fin de OnDrawCell tandis que l'objet Icone fait partie de la form, je le détruis donc dans le destructeur de celle-ci, ça me semble correct mais je peux me tromper.
    Tu as effectivement 2 objet mais tu oublie la reference de celui que tu alloue dans ta méthode pour la remplacer par celle de m_Icone (d'ou le memory leak).

    Par contre, je n'avais pas pensé au fait que si je donne la référence de Icone à IconeTest et que je détruis IconeTest, alors Icone est aussi détruit? Comment faire pour détruire IconeTest sans détruire Icone?
    IconeTest pointe sur la même reference (zone mémoire) que m_Icone
    donc delete de IconeTest => delete de m_Icone

    D'un autre côté, lorsque j'entre dans l'événement OnDrawCell, Icone est déjà nul, donc mon souci vient d'autre chose (même si le problème que tu soulèves existe)
    Est tu certain de cela?
    ensuite est tu certain que Init est appelé avant OnDrawCell?


    Autrement:
    Un petit tour par ici devrais t'aider

    http://cpp.developpez.com/faq/cpp/?p...tructeur_copie
    http://cpp.developpez.com/faq/cpp/?page=references
    http://c.developpez.com/faq/?page=pointeurs

    autrement concernant la phrase pas claire sur le constructeur par copie je verrai un truc du style

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Graphics::TBitmap *IconeTest = new Graphics::TBitmap(m_Icone);
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Graphics::TBitmap *IconeTest = new Graphics::TBitmap();
    // oubli de l'objet que je viens de créer (leak), et remplacement de sa référence
    IconeTest = m_Icone;
    bazar: http://www.improetcompagnie.com/publ...ctacles-6.html

    BÉPO la disposition de clavier francophone, ergonomique et libre: http://bepo.fr/wiki/Accueil

    Emacs Wiki: http://www.emacswiki.org/

    En attente de ce que produira: http://www.pushmid.com

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    39
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2009
    Messages : 39
    Points : 46
    Points
    46
    Par défaut
    Ahaha, quel couillon je suis... J'ai oublié d'enlever le Graphics::TBitmap * lors de l'initialisation, cette variable est devenue "locale". Voici le bon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void TForm_Main::initMainForm()
    {
         m_Icone = new Graphics::TBitmap;
         m_Icone->LoadFromFile(Images//IconeRouge.bmp);
    }
    Ainsi m_Icone est bien initialisé et non nul lors de l'événement OnDrawCell.

    Merci pour ton aide jabbounet, je vais aller lire ce que tu m'as montré et modifier mon code pour régler ce dernier problème...


    Bonne journée,

    Frédéric

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 18
    Dernier message: 21/10/2006, 19h10
  2. Garder en mémoire les valeurs entrées par l'utilisateur
    Par dessinateurttuyen dans le forum Langage
    Réponses: 11
    Dernier message: 17/08/2006, 09h15
  3. Garder en mémoire les identifiants FTP
    Par .:dev:. dans le forum Langage
    Réponses: 6
    Dernier message: 12/08/2006, 14h41
  4. garder en mémoire une dll
    Par mnaulet dans le forum C++
    Réponses: 2
    Dernier message: 09/08/2006, 12h36
  5. Réponses: 7
    Dernier message: 07/07/2006, 12h23

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