Partage
  • Partager sur Facebook
  • Partager sur Twitter

Libérer la mémoire avec SDL

Sujet résolu
    20 mars 2008 à 16:24:43

    Bonjour, j'ai fais un tetris en SDL / C++, il fonctionne bien seulement que la mémoire utilisée par le programme continue d'augmenter sans cesse à mesure que les pièce tombent.
    Par contre la mémoire est correctement libérée à la fin du programme.
    Je sais pas si quelqu'un a un conseil à me donner ou si sa peut venir d'ailleurs que des textures.

    voici les bouts de code qui s'occupe des textures:
    Main :
    1. espaceJeu = load_img("image/espaceJeu.bmp");
    2.     background = load_img("image/background.bmp");
    3.     boutonCommencer = load_img("image/boutonCommencer.bmp");
    4.     boutonPause = load_img("image/boutonPause.bmp");
    5.     boutonSortir = load_img("image/boutonSortir.bmp");
    6.     /* appelle de la fonction appliquerSurface() (voir plus bas) */
    7.     appliquerSurface(BOUTON_X, BOUTON_Y, boutonCommencer, background);
    8.     appliquerSurface(BOUTON_X, BOUTON_Y + INTERVALLE, boutonPause, background);
    9.     appliquerSurface(BOUTON_X, BOUTON_Y + (2*INTERVALLE), boutonSortir, background);
    10.     appliquerSurface(170, 130, espaceJeu, background);
    11.     appliquerSurface(0, 0, background, screen);
    12.     if(SDL_Flip(screen) == -1)
    13.        return 1;
    14.     deroulement(BOUTON_X, BOUTON_Y, INTERVALLE, espaceJeu, background, screen);
    15.     SDL_FreeSurface(espaceJeu);
    16.     SDL_FreeSurface(background);
    17.     SDL_FreeSurface(boutonCommencer);
    18.     SDL_FreeSurface(boutonPause);
    19.     SDL_Quit();
    20.     return 0;


    la fonction qui s'occupe de tout actualiser, donc qui charge tout :
    1. void actualiser(int forme, SDL_Surface *jeu, SDL_Surface *background, SDL_Surface *screen)
    2. {
    3.     int x1, y1, x2, y2, x3, y3, x4, y4;
    4.     SDL_Surface *texture = NULL, *jeuDefault = NULL;
    5.     static int table[LARGEUR][HAUTEUR] = {0}; // x est la largeur et y la hauteur
    6.     for(int x=0;x<=LARGEUR;x++)
    7.     {
    8.         for(int y=0;y<=HAUTEUR;y++){
    9.             table[x][y]=0;
    10.         }
    11.     }
    12.     jeuDefault = load_img("image/espaceJeu.bmp");
    13.     appliquerSurface(0, 0, jeuDefault, jeu); // permet de supprimer la position précédente.
    14.     switch(forme)
    15.     {
    16.         case 1:
    17.             texture = load_img("image/formeUne.bmp");
    18.             x1 = formeCarre.rechercheXP();
    19.             y1 = formeCarre.rechercheYP();
    20.             x2 = formeCarre.rechercheXS();
    21.             y2 = formeCarre.rechercheYS();
    22.             x3 = formeCarre.rechercheXT();
    23.             y3 = formeCarre.rechercheYT();
    24.             x4 = formeCarre.rechercheXQ();
    25.             y4 = formeCarre.rechercheYQ();
    26.             for(int x=0; x<=LARGEUR;x++)
    27.             {
    28.                 for(int y=0;y<=HAUTEUR;y++)
    29.                 {
    30.                     table[x][y]=formeCarre.tableauPose(x, y, RECEVOIR, 0);
    31.                 }
    32.             }
    33.             break;
    34.         case 2:
    35.             texture = load_img("image/formeDeux.bmp");
    36.             x1 = formeRaccordun.rechercheXP();
    37.             y1 = formeRaccordun.rechercheYP();
    38.             x2 = formeRaccordun.rechercheXS();
    39.             y2 = formeRaccordun.rechercheYS();
    40.             x3 = formeRaccordun.rechercheXT();
    41.             y3 = formeRaccordun.rechercheYT();
    42.             x4 = formeRaccordun.rechercheXQ();
    43.             y4 = formeRaccordun.rechercheYQ();
    44.             for(int x=0; x<=LARGEUR;x++)
    45.             {
    46.                 for(int y=0;y<=HAUTEUR;y++)
    47.                 {
    48.                     table[x][y]=formeRaccordun.tableauPose(x, y, RECEVOIR, 0);
    49.                 }
    50.             }
    51.             break; /* jusqu'à case 7... */
    52.     }
    53.     appliquerSurface(x1, y1, texture, jeu);
    54.     appliquerSurface(x2, y2, texture, jeu);
    55.     appliquerSurface(x3, y3, texture, jeu);
    56.     appliquerSurface(x4, y4, texture, jeu);
    57.     for(int x=0; x<=LARGEUR;x++)    /* sert à appliquer les surface des pièces deja posées */
    58.     {
    59.         for(int y=0;y<=HAUTEUR;y++)
    60.         {
    61.             if(table[x][y]!=0)
    62.             {
    63.                 switch(table[x][y])
    64.                 {
    65.                     case 1:
    66.                         texture = load_img("image/formeUne.bmp");
    67.                         break;
    68.                     case 2:
    69.                         texture = load_img("image/formeDeux.bmp");
    70.                         break;
    71.                     case 3:
    72.                         texture = load_img("image/formeTrois.bmp");
    73.                         break;
    74.                     case 4:
    75.                         texture = load_img("image/formeQuatre.bmp");
    76.                         break;
    77.                     case 5:
    78.                         texture = load_img("image/formeCinq.bmp");
    79.                         break;
    80.                     case 6:
    81.                         texture = load_img("image/formeSix.bmp");
    82.                         break;
    83.                     case 7:
    84.                         texture = load_img("image/formeSept.bmp");
    85.                         break;
    86.                 }
    87.                 appliquerSurface(x*DIMENSION_PIECE, y*DIMENSION_PIECE, texture, jeu);
    88.             }
    89.         }
    90.     }
    91.     appliquerSurface(170, 130, jeu, background);
    92.     appliquerSurface(0, 0, background, screen);
    93.     SDL_Flip(screen);
    94.     SDL_FreeSurface(texture);
    95.     SDL_FreeSurface(jeuDefault);

    et pour finir voila la fonction qui charge les images (sert à les convertir en 32bits )
    1. SDL_Surface *load_img(std::string filename)
    2. {
    3.     SDL_Surface *imageChargee = NULL;
    4.     SDL_Surface *imageOptimisee = NULL;
    5.     imageChargee = SDL_LoadBMP(filename.c_str());
    6.     if(imageChargee != NULL)
    7.     {
    8.         imageOptimisee = SDL_DisplayFormat(imageChargee);
    9.         SDL_FreeSurface(imageChargee);  // libère la mémoire
    10.     }
    11.     /* on retourne l'image que l'on a traitée pour que se soit du 32 bits */
    12.     return imageOptimisee;
    13. }

    et la fonction qui applique les surfaces :
    1. void appliquerSurface(int x, int y, SDL_Surface *source, SDL_Surface *destination)
    2. {
    3.     SDL_Rect coordonnee;
    4.     coordonnee.x = x;
    5.     coordonnee.y = y;
    6.     SDL_BlitSurface(source, NULL, destination, &coordonnee);
    7. }


    bon voila c'est tout, désolé pour la quantité de code que j'ai mis d'un coup mais j'ai vraiment aucune idée d'où l'erreur peut venir.
    Merci d'avance :)
    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      20 mars 2008 à 19:21:54

      Tu sais comment libérer la mémoire en c? Si oui, je pense qu'il suffit de libérer la mémoire à chaque déplacement d'une pièce.
      Je ne sais pas si je répond à la question où si je n'ai rien compris.
      • Partager sur Facebook
      • Partager sur Twitter
        20 mars 2008 à 21:00:03

        Dans actualiser :
        Ton switch(forme) alloue au moins une texture, dans la variable éponyme. Le souci, c'est que tu te ressers de cette même variable sans libérer la surface qui a été préalablement allouée ! En fait, tu ne libères que la dernière surface allouée. D'où fuites.

        Ensuite, change-moi ceci avant de te faire lyncher par les grands pontes du C++ :
        1. SDL_Surface *load_img(std::string filename)
        2. // devient
        3. SDL_Surface *load_img(const std::string & filename)


        Le const est complètement facultatif, mais c'est une bonne habitude. La référence aussi me diras-tu, mais là par contre, ça évite des tas de copies inutiles ;)
        • Partager sur Facebook
        • Partager sur Twitter
          20 mars 2008 à 21:44:50

          ok je crois que je vois ce que tu veux dire et je comprend pourquoi c'est mal aloué mais alors j'ai essayé de le modifié d'après tes conseil et sa me referme directement sans erreur (comme si un pointeur était au mauvais endroit ou un truc du genre)
          voila le code avec les modification apportée, je sais pas si c'est bien sa que tu voulais dire..
          1. void actualiser(int forme, SDL_Surface *jeu, SDL_Surface *background, SDL_Surface *screen)
          2. {
          3.     int x1, y1, x2, y2, x3, y3, x4, y4;
          4.     SDL_Surface *texture = NULL, *jeuDefault = NULL;
          5.     static int table[LARGEUR][HAUTEUR] = {0};
          6.     for(int x=0;x<=LARGEUR;x++)
          7.     {
          8.         for(int y=0;y<=HAUTEUR;y++){
          9.             table[x][y]=0;
          10.         }
          11.     }
          12.     jeuDefault = load_img("image/espaceJeu.bmp");
          13.     SDL_FreeSurface(jeu);   /* sa pour libérer la surface jeu comme de toute façon on y applique une autre surface */
          14.     appliquerSurface(0, 0, jeuDefault, jeu);
          15.     switch(forme)
          16.     {
          17.         case 1:
          18.             texture = load_img("image/formeUne.bmp");
          19.             x1 = formeCarre.rechercheXP();
          20.             y1 = formeCarre.rechercheYP();
          21.             x2 = formeCarre.rechercheXS();
          22.             y2 = formeCarre.rechercheYS();
          23.             x3 = formeCarre.rechercheXT();
          24.             y3 = formeCarre.rechercheYT();
          25.             x4 = formeCarre.rechercheXQ();
          26.             y4 = formeCarre.rechercheYQ();
          27.             for(int x=0; x<=LARGEUR;x++)
          28.             {
          29.                 for(int y=0;y<=HAUTEUR;y++)
          30.                 {
          31.                     table[x][y]=formeCarre.tableauPose(x, y, RECEVOIR, 0);
          32.                 }
          33.             }
          34.             break;
          35.         /* etc. jusqu'à case 7 */
          36.     }
          37.     appliquerSurface(x1, y1, texture, jeu);
          38.     appliquerSurface(x2, y2, texture, jeu);
          39.     appliquerSurface(x3, y3, texture, jeu);
          40.     appliquerSurface(x4, y4, texture, jeu);
          41.     SDL_FreeSurface(texture);/*et ici pour effacer afin que le pointeur soit vide pour y placer une autre image */
          42.     for(int x=0; x<=LARGEUR;x++)
          43.     {
          44.         for(int y=0;y<=HAUTEUR;y++)
          45.         {
          46.             if(table[x][y]!=0)
          47.             {
          48.                 switch(table[x][y])
          49.                 {
          50.                     case 1:
          51.                         texture = load_img("image/formeUne.bmp");
          52.                         break;
          53.                     case 2:
          54.                         texture = load_img("image/formeDeux.bmp");
          55.                         break;
          56.                     case 3:
          57.                         texture = load_img("image/formeTrois.bmp");
          58.                         break;
          59.                     case 4:
          60.                         texture = load_img("image/formeQuatre.bmp");
          61.                         break;
          62.                     case 5:
          63.                         texture = load_img("image/formeCinq.bmp");
          64.                         break;
          65.                     case 6:
          66.                         texture = load_img("image/formeSix.bmp");
          67.                         break;
          68.                     case 7:
          69.                         texture = load_img("image/formeSept.bmp");
          70.                         break;
          71.                 }
          72.                 appliquerSurface(x*DIMENSION_PIECE, y*DIMENSION_PIECE, texture, jeu);
          73.             }
          74.         }
          75.     }
          76.     appliquerSurface(170, 130, jeu, background);
          77.     appliquerSurface(0, 0, background, screen);
          78.     SDL_Flip(screen);
          79.     SDL_FreeSurface(texture);
          80.     SDL_FreeSurface(jeuDefault);
          81. }


          voila c'est bien ça que tu disais ? merci je savais pas que il fallait libérer avant de reremplir.
          • Partager sur Facebook
          • Partager sur Twitter
            20 mars 2008 à 21:49:20

            Tu viens d'en corriger une seule là !
            Y'a la même dans le switch() de ton for !
            Ajoute donc un SDL_FreeSurface() après la fonction appliquerSurface contenue dans cette (double !) boucle ;)

            Au fait, si c'est destiné à être appelé plusieurs fois, je ne saurais que trop te conseiller de mettre ces surfaces "en cache" : dans un tableau, un vector, une map... Cela te simplifierait un peu les choses, et éviterait surtout d'avoir à allouer/désallouer constamment des surfaces...
            • Partager sur Facebook
            • Partager sur Twitter
              20 mars 2008 à 22:19:07

              Hello alors merci beaucoup c'était bien ça ... maintenant sa marche nickel ...et merci bien pour les conseils !!

              je suis assez débutant alors je connais que les base et les technique comme les vector ou map j'ai jamais entendu ...

              Merci Bonne fin de soirée :D
              • Partager sur Facebook
              • Partager sur Twitter
                20 mars 2008 à 22:22:02

                Ca deviendra vite de grands amis :D
                • Partager sur Facebook
                • Partager sur Twitter

                Libérer la mémoire avec SDL

                × 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