Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème d'extinction du programme

Sujet résolu
    12 juin 2007 à 19:22:28

    Bonjour, je suis actuellement en train de programmer une classe "SDL" qui pourrait prendre en charge les applications de la SDL pour que ça soit plus simple pour l'utilisateur (moi, quand j'aurais terminer la classe :lol: ). Seulement mon code ne marche pas d'où: problème. :colere2:
    En fait il s'eteint quand j'apuis sur la flêche du haut (ce qui, vous allez le voire, appelle la fonction "affiche" de la classe).

    Je ne vous montre que ce qui est important, à savoire:

    le main.cpp:
    #include <iostream>
    #include <string>
    #include <SDL/SDL.h>
    #include <SDL/SDL_Image.h>
    #include <SDL/SDL_ttf.h>
    #include "SDL.h"


    using namespace std;


    int main(int argc, char *argv[])
    {
      SDL_Event event;
      int continuer=1;
      SDL_Surface*ecran;
      int affiche1=0;

      /* initialisation de la SDL*/
      SDL_Init(SDL_INIT_VIDEO);
      SDL_WM_SetCaption("   Test c++ et classe SDL  ", NULL);
      SDL_WM_SetIcon(IMG_Load("nuinui6.png"), NULL);
      ecran = SDL_SetVideoMode( 1000  ,  800  , 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
      SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));


      /*création des  objets de type SDL*/
      SDL menu1(ecran, "surf.jpg", 0, 0);

    while (continuer)
    {
        SDL_WaitEvent(&event);
         switch(event.type)
            {
                case SDL_QUIT:
                    continuer = 0;
                    break;

                case SDL_KEYDOWN  :
                switch (event.key.keysym.sym)
                {
                    case SDLK_UP:
                    affiche1=1;
                    break;
                }
                break;
            }
            if (affiche1)
            menu1.affiche();
    }




        menu1.Free();
        SDL_Quit();
        return EXIT_SUCCESS;
    }


    le "SDL.h":
    #ifndef DEF_SDL
    #define DEF_SDL

    class SDL
    {
        public:
        SDL (SDL_Surface*, const char*nom="",long x=0, long y=0);//constructeur

        void SetNom(const char *);//changer le nom
        void setPos (long,long);//changer la position
        void SetTrans(long, long, long);//changer la transaparence
        void SetTransA(long);// changer la transparence alpha
        void SetColor(long, long, long);//changer la couleure
        void SetTexte(const char*, const char*, long);
        void Free();
        void affiche();



        private:
        //position
        long m_x, m_y;

        //transparence
        bool m_t, m_tA;
        long m_setTransA;
        long m_setTransC[3];

       //couleur et contenue
        bool m_color;
        long m_setColor [3];
        const char *m_nom;

        //texte
         bool m_texte;
         const char*m_message;
         const char*m_police;
         long m_taille;

         //Surface
         SDL_Surface *m_surface;
         SDL_Surface *ecran;
    };


    #endif




    et enfin le constructeur (je pense que cela peut être important) et la fonction "affiche:
    SDL::SDL (SDL_Surface*ecran1, const char*nom ,long x, long y)
    {
            ecran=ecran1;
            m_nom=nom;
            m_x=x;
            m_y=y;
            m_t=false;
            m_tA=false;
            m_setTransA=0;
            m_setTransC[3]=0;
            m_color= false;
            m_setColor[3]=0;
            m_texte=false;
            m_surface=NULL;
            m_message=NULL;
            m_police =NULL;
            m_taille=0;
    }


    void SDL::affiche()
    {
       if(!m_texte)
       {
        m_surface=IMG_Load(m_nom);
        SDL_Rect position;

        position.x=m_x;
        position.y=m_y;

        if (m_t)
        {
        SDL_SetColorKey(m_surface , SDL_SRCCOLORKEY, SDL_MapRGB( m_surface ->format, m_setTransC[0], m_setTransC[1], m_setTransC[2]));
        }
        else if (m_tA)
        {
        SDL_SetAlpha(m_surface, SDL_SRCALPHA, m_setTransA);
        }

        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
        SDL_BlitSurface(m_surface, NULL, ecran, &position);
        SDL_Flip(ecran);
       }
       else
        {
        SDL_Rect position;

        SDL_Color couleur = {m_setColor[0], m_setColor[1], m_setColor[2]};
        TTF_Font *police = NULL;
        police = TTF_OpenFont(m_police, m_taille);
        m_surface = TTF_RenderText_Blended(police, m_message , couleur);

        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
        SDL_BlitSurface(m_surface, NULL, ecran, &position);
        SDL_Flip(ecran);
        }

    }


    Merci de toute vos future réponses.
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      12 juin 2007 à 20:31:04

      Peut-être est-ce dû à un dépassement de mémoire, car en une fonction (qui, je le rappelle, est rappelée à chaque tour de boucle), tu arrives quand mêmes à avoir comme fuite 2 surfaces SDL et 1 police :p
      • Partager sur Facebook
      • Partager sur Twitter
        12 juin 2007 à 21:07:47

        Ca ne marche toujours pas.
        J'ai bien vérifié et il n'y avait qu'une fuite, celle de l'ecran dans la classe SDL, et j'y ai tout de suite remédié (l'autre surface était en fait libéré par la fonction "Free" , dans le main.cpp.

        Voici mes changement.

        SDL.h (cette fois ci je vous met tout le code)
        #ifndef DEF_SDL
        #define DEF_SDL

        class SDL
        {
            public:
            SDL (SDL_Surface*, const char*nom="",long x=0, long y=0);//constructeur

            void SetNom(const char *);//changer le nom
            void setPos (long,long);//changer la position
            void SetTrans(long, long, long);//changer la transaparence
            void SetTransA(long);// changer la transparence alpha
            void SetColor(long, long, long);//changer la couleure
            void SetTexte(const char*, const char*, long);
            void Free();
            void affiche();



            private:
            //position
            long m_x, m_y;

            //transparence
            bool m_t, m_tA;
            long m_setTransA;
            long m_setTransC[3];

           //couleur et contenue
            bool m_color;
            long m_setColor [3];
            const char *m_nom;

            //texte
             bool m_texte;
             const char*m_message;
             const char*m_police;
             long m_taille;

             //Surface
             SDL_Surface *m_surface;
             SDL_Surface *ecran;
             TTF_Font *police;
        };


        #endif

        (j'ai juste rajouté "TTF_Font *police")


        SDL.cpp
        #include <iostream>
        #include <string>
        #include <SDL/SDL.h>
        #include <SDL/SDL_Image.h>
        #include <SDL/SDL_ttf.h>

        #include "SDL.h"

        using namespace std;

        SDL::SDL (SDL_Surface*ecran1, const char*nom ,long x, long y)
        {
                ecran=ecran1;
                m_nom=nom;
                m_x=x;
                m_y=y;
                m_t=false;
                m_tA=false;
                m_setTransA=0;
                m_setTransC[3]=0;
                m_color= false;
                m_setColor[3]=0;
                m_texte=false;
                m_surface=NULL;
                m_message=NULL;
                m_police =NULL;
                m_taille=0;
                police=NULL;
        }

        void SDL::SetNom(const char *nom)//changer le nom
        {
            m_color=false;
            m_nom=nom;
        }


        void SDL::setPos (long x=0,long y=0)//changer la position
        {
            m_x=x;
            m_y=y;
        }


        void SDL::SetTrans(long a, long b, long c)//changer la transaparence
        {
               m_t=true;
               m_tA=false;

               m_setTransC[0]= a;
               m_setTransC[1]= b;
               m_setTransC[2]= c;

        }

        void SDL::SetTransA(long a)// changer la transparence alpha
        {
            m_t=false;
            m_tA=true;

            m_setTransA=a;
        }

        void SDL::SetColor(long a, long b, long c)//changer la couleur
        {
            m_color=true;

            m_setColor[0]= a;
            m_setColor[1]= b;
            m_setColor[2]= c;
        }

        void SDL::SetTexte(const char* message, const char* police, long taille)
        {
            m_message=message;
            m_police=police;
            m_taille=taille;
        }

        void SDL::Free()//pour libérer la surface;
        {
          SDL_FreeSurface (m_surface);
          SDL_FreeSurface (ecran);
          if (m_texte)
          TTF_CloseFont(police);
        }


        void SDL::affiche()
        {
           if(!m_texte)
           {
            m_surface=IMG_Load(m_nom);
            SDL_Rect position;

            position.x=m_x;
            position.y=m_y;

            if (m_t)
            {
            SDL_SetColorKey(m_surface , SDL_SRCCOLORKEY, SDL_MapRGB( m_surface ->format, m_setTransC[0], m_setTransC[1], m_setTransC[2]));
            }
            else if (m_tA)
            {
            SDL_SetAlpha(m_surface, SDL_SRCALPHA, m_setTransA);
            }

            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
            SDL_BlitSurface(m_surface, NULL, ecran, &position);
            SDL_Flip(ecran);
           }
           else
            {
            SDL_Rect position;

            SDL_Color couleur = {m_setColor[0], m_setColor[1], m_setColor[2]};
            police = TTF_OpenFont(m_police, m_taille);
            m_surface = TTF_RenderText_Blended(police, m_message , couleur);
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
            SDL_BlitSurface(m_surface, NULL, ecran, &position);
            SDL_Flip(ecran);
            }

        }

        J'ai changé l'implémentation de Free et de Affiche.


        J'ai toujours la même erreur: le programme s'éteint lorsque j'appuie sur la flêche du haut.

        HEELLPP..... :(
        S'il vous plait........


        :euh:
        Il y a quelqu'un? :-°
        • Partager sur Facebook
        • Partager sur Twitter
          14 juin 2007 à 8:58:12

          je suis pas sur mais je crois que
          m_setColor[3]=0;


          n'est pas une initialisation valide.. si? logiquement tu devrais avoir
          m_setColor[0]=0;
          m_setColor[1]=0;
          m_setColor[2]=0;
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            14 juin 2007 à 10:13:55

            Et je maintiens pour mes fuites, tu en as toujours 3 dans la méthode affiche ^^ :

            m_surface=IMG_Load(m_nom);
            /* ... */
            police = TTF_OpenFont(m_police, m_taille);
            /* ... */
            m_surface = TTF_RenderText_Blended(police, m_message , couleur);


            Ces trois fonctions sont à accompagner obligatoirement d'un SDL_FreeSurface ou TTF_CloseFont.
            De toute manière, pour t'arranger les choses, je te conseille de charger une fois pour toute ces surfaces/polices et de ne pas les charger à chaque affichage, ça ralentit ton programme en plus.

            Pour la désallocation, quitte à utiliser une classe, pourquoi ne pas utiliser le destructeur ?
            • Partager sur Facebook
            • Partager sur Twitter
              14 juin 2007 à 13:48:24

              J'ai réussi, ça marche! :D
              En fait, comme vous me l'avez consseillez, maintenant je charge l'image et la police dans respectivement "setNom" et "setTexte".
              Et je n'ai plus qu'a blité dans la fonction affiche.
              La il n'y a plus de fuite de mémoire normalement, non?
              Si je charge l'image une bonne fois pour toute dans "setNom" et pareil pour la police et que j'appelle la fonction "free" à la fin (que je vais tout de suite remplacé par un désctructeur comme me l'a conseillé cyprien_ ) pour libérer le tout il n'y plus de fuite de mémoire (enfin je pense :-° )?
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                14 juin 2007 à 16:56:03

                Juste encore un détail, lorsque tu fais TTF_RenderText_Blended n'oublie pas, là non plus, de désallouer la mémoire (je précise car tu n'en as pas parlé dans ton post).
                Lorsque tu appelles les méthodes setNom ou setTexte, fait attention à désallouer si tu avais déjà alloué quelque chose (au cas où tu les appelles plusieurs fois dans le programme en fait).
                Après ça, il ne devrait plus y avoir de fuites, mais on ne sait jamais. Le meilleur moyen de s'en assurer, c'est de laisser tourner son programme et de regarder la place qu'il prend en RAM ( Ctrl+Alt+suppr >> Onglet processus (sous Windows uniquement)).
                • Partager sur Facebook
                • Partager sur Twitter
                  14 juin 2007 à 18:48:35

                  Ok merci, mon programme fonctionne et sans fuite maintenant :) .
                  Une dernière chose, simple curiosité: quand on a une fuite, et qu'on ne s'en rend pas compte, il se peut que notre programme prenne de plus en plus de mémoire vive, mais y a t'il un moment où windows prend les choses en main et arrêtes le program ou donne un méssage d'alerte?
                  Et la mémoire prise dans la mémoire vive qu'on a pas désaloué, reste elle là j'usqu'a ce qu'on redémare l'ordinateur ou est ce que, une fois encore, windows libère cette mémoire qui ne sert à rien au bout d'un moment?
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    14 juin 2007 à 19:07:51

                    Bah oui, puisqu'il y un moment où la mémoire est pleine :D
                    Pour la 2e question, là je ne sais pas trop :euh:
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 juin 2007 à 19:48:09

                      La plupart des OS collectent la mémoire que tu n'as pas libérée, mais ils le font de manière assez lente et assez couteuse. Ton processeur verra souvent sa charge augmenter dans ce genre d'opérations, donc il vaut mieux bien libérer sa mémoire avant de quitter le programme.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        14 juin 2007 à 19:56:27

                        Et, y a t'il un moyen de désalloué "manuellement" (quand le programme est terminé) la mémoire?
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          14 juin 2007 à 19:59:29

                          Je ne pense pas et de toute manière, mieux vaut tout désallouer proprement dans le programme.

                          Ah si, il y a un moyen ! Tu appuies sur la touche Windows (avec une fenêtre) puis la flèche haut, puis Enter, puis la flèche droite et enfin Enter :D
                          • Partager sur Facebook
                          • Partager sur Twitter
                            14 juin 2007 à 23:18:52

                            pour les fuite de mémoire, voir aussi valgrind.. (google est ton ami)
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Problème d'extinction du programme

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown