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

SDL Discussion :

[CPU - Fuites de mémoires] Aide sur mon code C.


Sujet :

SDL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1
    Points : 3
    Points
    3
    Par défaut [CPU - Fuites de mémoires] Aide sur mon code C.
    Bonjour,

    Il y a encore quelques mois, je codais très mal : aucune structure; peu de fonctions; aucun prototype...

    J'ai donc décidé d'améliorer son code, après avoir fais une rapide ré-indentation et une mise en place de prototypes protégés contre les inclusions multiples; je m'attaque aux fuites de mémoires .

    J'ai rajouté quelques free_Surface() mais le problème de fuite de mémoire persiste.

    Voici mon code non optimisé :
    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
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    #include "Autres.h"
    #include "Charger_Et_Sauvegarder.h"
    #include "Jeu.h"
    #include "Options.h"
    #include "Son.h"
     
    #include <SDL_image.h>
     
    /*-------Redirige l'utilisateur a la partie du programme où il veut aller-------*/
    void menu_Et_Redirigement( SDL_Surface *ecran, int i )
    {
        SDL_Surface *menu = NULL, *viseur[2] = {NULL};
        SDL_Rect position_Menu, position_Viseur;
        SDL_Event event;
     
        int continuer = 1;
     
        position_Menu.x = 0;
        position_Menu.y = 0;
     
     
        menu = IMG_Load( "ressources/images/menu_Jouer.png" );
        viseur[0] = IMG_Load( "ressources/viseurs/viseur.png" );
        viseur[1] = IMG_Load( "ressources/viseurs/viseur_Gras.png" );
     
        /* Blit time ! */
        SDL_BlitSurface( menu, NULL, ecran, &position_Menu );
        SDL_BlitSurface( viseur[0], NULL, ecran, &position_Viseur );
     
        if( i == TRUE )
        {
            AUDIO_Jouer_Musique( 1 );
        }
     
        while ( continuer )
        {
     
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
     
            SDL_WaitEvent(&event);
     
            switch(event.type)
            {
     
            case SDL_QUIT:
     
                AUDIO_Jouer_Musique(MSQ_NULL);
                SDL_FreeSurface( menu );
     
                quitter();
                break;
     
            case SDL_KEYDOWN:
     
                switch(event.key.keysym.sym)
                {
                case SDLK_KP1:
     
                    AUDIO_Jouer_Musique(MSQ_NULL);
     
                    SDL_FreeSurface( menu );
                    SDL_FreeSurface( viseur[0] );
                    SDL_FreeSurface( viseur[1] );
                    jouer( ecran );
     
                    break;
     
                case SDLK_KP2:
     
                    AUDIO_Jouer_Musique(MSQ_NULL);
     
                    SDL_FreeSurface( menu );
                    SDL_FreeSurface( viseur[0] );
                    SDL_FreeSurface( viseur[1] );
                    voir_Score( ecran );
     
                    break;
     
                case SDLK_KP3:
     
                    AUDIO_Jouer_Musique(MSQ_NULL);
                    SDL_FreeSurface( menu );
                    SDL_FreeSurface( viseur[0] );
                    SDL_FreeSurface( viseur[1] );
                    options( ecran );
     
                    break;
     
                default:
                    break;
                }
     
                break;
     
            case SDL_MOUSEBUTTONDOWN:
     
                /* Si l'on clique au bon endroit ou pas. */
     
                if( event.button.x > 55 && event.button.x < 220 &&
                        event.button.y > 190 && event.button.y < 225 )
                {
     
                    AUDIO_Jouer_Musique(MSQ_NULL);
                    SDL_FreeSurface( menu );
                    SDL_FreeSurface( viseur[0] );
                    SDL_FreeSurface( viseur[1] );
                    jouer( ecran );
                }
     
                else if( event.button.x > 45 && event.button.x < 530 &&
                         event.button.y > 250 && event.button.y < 285 )
                {
     
                    SDL_FreeSurface( menu );
                    SDL_FreeSurface( viseur[0] );
                    SDL_FreeSurface( viseur[1] );
                    voir_Score( ecran );
                }
     
                else if( event.button.x > 45 && event.button.x < 308 &&
                         event.button.y > 308 && event.button.y < 348 )
                {
                    SDL_FreeSurface( menu );
                    SDL_FreeSurface( viseur[0] );
                    SDL_FreeSurface( viseur[1] );
     
                    options( ecran );
                }
     
                else
                {
                    AUDIO_Jouer_Son(SON_TIR_LOUPE);
                }
     
                break;
     
            case SDL_MOUSEMOTION:
     
                position_Viseur.x = event.motion.x - 15;
                position_Viseur.y = event.motion.y - 15;
     
                break;
     
            default:
                break;
     
            }
     
            /* Blit time ! */
     
            SDL_BlitSurface( menu, NULL, ecran, &position_Menu );
     
                if( ( event.motion.x > 55 && event.motion.x < 220 &&
                    event.motion.y > 190 && event.motion.y < 225 ) ||
                    ( event.button.x > 45 && event.button.x < 530 &&
                      event.button.y > 250 && event.button.y < 285 ) ||
                    ( event.button.x > 45 && event.button.x < 308 &&
                      event.button.y > 308 && event.button.y < 348 ) )
                {
                    SDL_BlitSurface( viseur[1], NULL, ecran, &position_Viseur );
                }
     
                else
                {
                    SDL_BlitSurface( viseur[0], NULL, ecran, &position_Viseur );
                }
     
            SDL_Flip( ecran );
     
        }
    }
    Comme je vous l'ai dis plus haut, ce code est horrible; je vous le promets, je insérerai - créerai plusieurs fonctions, structures...

    Ceci n'est qu'une petite partie de mon programme, mais si vous pourriez m'aider pour réduire l'utilisation de CPU qui est d'environ 50 % lorsque l'on bouge la souris et enlever les fuites de mémoires; cela m'aiderai beaucoup.

    Merci d'avance !


    ---paraze---

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 28
    Points : 25
    Points
    25
    Par défaut SDL_Delay
    Salut,

    Effectivement, ton code emploie une structure particulièrement sauvage et j'avoue que j'ai eu un peu la flemme de fouiller dans ta boucle principale...

    Pour ce qui est des 50% d'utilisation CPU, j'avais eu le même problème au départ. Je l'avais réglé en ajoutant un SDL_Delay(int duree) en fin de boucle générale, ce qui permet à l'ordinateur de souffler un peu avant de reprendre le boulot. La "duree" est un entier qui indique le temps de la pause en millisecondes : 30 est une bonne valeur.

    Sinon, pour les questions de performance, je te conseille quand même de ne plus te contenter seulement de la SDL, dont les processus graphiques sont assez lourds, mais de la combiner avec OpenGL, comme l'explique ce tutoriel.

    Pour ce qui est des fuites mémoires, j'ai du mal à voir. Je vais donc te copier/coller le conseil qui m'a été donné il y a plusieurs années, lorsque j'ai eu le même problème, et qui est la solution tôt ou tard inévitable pour les questions de mémoire :

    Je te conseille la solution radicale du "memory manager"
    en gros, un outil intégré à ton code qui va tracer les allocations et désallocations mémoire et te permettre de trouver des fuites sans te prendre la tête durant des heures

    sur le site de Paul Nettle, vas dans la rubrique Code et dans le menu à gauche sélectionne MMGR - The memory manager

    intègres les 3 fichiers à ton projet
    inclus mmgr.h dans ton (tes) fichier(s) cpp (ou c)
    et lance ton appli, des ficheirs de log seront créés lorsque tu quitteras
    bonne chance
    Bonne chance, donc.

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 859
    Points : 218 579
    Points
    218 579
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Personnellement je conseille la restructuration du programme avant de boucher les fuites de mémoire.

    Sinon, comment faites vous pour voir qu'il y a des fuites de mémoire ?
    Moi personnellement, sous Linux, j'utilise valgrind qui est un très bon outil pour ce genre de chose.

    Pour l'utilisation du CPU, un SDL_Delay va aider. Mais je conseille aussi de ne pas trop le faire n'importe comment.
    Le deuxième problème que vous avez, c'est d'utiliser un SDL_WaitEvent(). Je pense que vous devriez utliser un SDL_PollEvent() (mais dans ce cas là, vous êtes plus qu'obliger d'avoir un SDL_Delay ... car le SDL_PollEvent, ne vas pas stopper le programme en attente d'un évènement.

    Et je vois qu'il y a des SDL_FreeSurface() dans votre boucle principale ... houlà ... déjà tout ce qui est gestion mémoire, cela prend du temps ... mais en plus dans une boucle principale, cela montre qu'il y a un problème de conception.

    Normalement, ce que l'on fait c'est que toute allocations (LoadBMP() par exemple) se fait avant la boucle principale, et jamais dedans, et les libérations (SDL_FreeSurface()) après la boucle principale (et pas dedans non plus). De toute façon, cela aide à avoir moins d'erreurs, mais aussi moins de fuites (car la structure est plus propre)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Membre expérimenté

    Profil pro
    Programmeur
    Inscrit en
    Août 2002
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Programmeur

    Informations forums :
    Inscription : Août 2002
    Messages : 1 091
    Points : 1 679
    Points
    1 679
    Par défaut
    Pour voir qu'il y a des fuites de mémoire il y a plusieurs moyens :
    - le premier est de faire tourner le programme avec toutes ses fonctionalités en boucle et voir que la mémoire utilisée augmente constamment dans le moniteur de tâches.
    - le deuxième un peu plus rigoureux est de tracer toutes les allocations, soit directement à la source avec un remplaçage de new/malloc, soit avec un runtime de debug qui permet le traçage des allocations. Lors de la sortie du programme le pool d'allocations doit être "clean".

    Ceci dit, il peut y avoir des fuites liées à l'utilisation d'une API (un objet d3d qui a eu un Get() sans Release()) et dans ce cas il faut utiliser le mode de débogage de ces APIs.

    Après pour trouver la source de ces fuites, si il n'y a aucun indice ou un code imbitable, les outils de traçage peuvent être sous forme de macros qui enregistrent la ligne de code qui a fait l'allocation et/ou la pile d'appel au moment du malloc (et donc celles qui restent à la destruction de l'application peuvent être raccrochées à la ligne précise d'allocation).
    Ensuite une inspection manuelle et exhaustive des malloc/new/createXX etc peut être faite tout en vérifiant que pour chaque appel de création d'objet il y a un appel de destruction d'objet (si possible symétrique).

    La correction peut être plus ou moins complexe s'il y a des interdépendances comme des compteurs de références etc. D'où l'intérêt d'être très rigoureux lors de l'écriture de son code (et de comprendre ce que fait son code).

    Un caveat : même si pour les raisons de débogage il est préférable de désallouer manuellement tout objet alloué, parfois en pratique dans le code final délivré à l'utilisateur il est beaucoup plus rapide de simplement tout laisser tomber à la sortie de l'application. La raison est que la désallocation doit toucher TOUS les objets (parfois par milliers ou millions), avec les problèmes de parcours de structure, d'invalidation du cache etc. Alors que les OS modernes peuvent libérer les pages allouées en un éclair et ne souffrent pas si des allocations locales à l'application restent sur le tas à la fermeture. Il est toujours important de désallouer les ressources partagées par contre si l'OS ne maintient pas un refcount lié à la durée de vie du process.

    LeGreg

    Mon site web | Mon blog | Mes photos | Groupe USA
    > BONJOUR, JE SUIS NOUVEAU SUR CE FORUM
    > presse la touche caps lock, stp
    > OH.. MERCI C EST BEAUCOUP PLUS FACILE COMME CA

Discussions similaires

  1. Demande d'aide sur mon code en C
    Par tekos22 dans le forum Débuter
    Réponses: 7
    Dernier message: 31/12/2009, 10h08
  2. Demande d'aide sur mon code
    Par b.soufiane dans le forum C++
    Réponses: 6
    Dernier message: 07/12/2007, 16h36
  3. Aide sur mon Code !
    Par b.soufiane dans le forum C
    Réponses: 10
    Dernier message: 07/12/2007, 12h38
  4. svp un peu d'aide sur mon update, resumé simple en dessous
    Par hansaplast dans le forum Langage SQL
    Réponses: 11
    Dernier message: 14/11/2005, 10h14
  5. [Language] Aide sur mon premier programme Java?
    Par hash2zo dans le forum Langage
    Réponses: 15
    Dernier message: 27/09/2005, 19h26

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