Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8
  1. #1
    Candidat au titre de Membre du Club
    Homme Profil pro quentin rausch
    Étudiant
    Inscrit en
    juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Nom : Homme quentin rausch
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : juin 2012
    Messages : 22
    Points : 10
    Points
    10

    Par défaut Problème de mémoire virtuelle

    Bonjour à tous,

    je suis actuellement en train d'afficher un signal en temps réel grâce à SDL.
    Pour cela je fais :

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
     
    SDL_Surface * truc;
     
    int main()
    {
     
         while(!done)
         {
           dessin_du_background();
           dessin_du_signal();
     
           if (press key = echap)
            done = 1;
         }
     
    SDL_FreeSurface(truc);
     
    }
    donc j'affiche mon background, puis je mets mon signal sur ce background, et je répéte l'opération jusqu'à ce que l'utilisateur quitte le logiciel. Je fais une sorte de gros sandwich de surfaces qui s'ajoutent les unes sur les autres.

    En faisant cela, (en regardant sur task manager), j'observe que la mémoire virtuelle de mon programme n'est pas libérée. elle est seulement libérée à la fin de mon main(), du coup elle augmente jusqu'à ce que l'ordinateur soit à bout de souffle et me dise qu'il doive arrêter de tourner.


    Ma question est la suivante: comment libérer cette mémoire tout en gardant une rapidité d’exécution ? parce que je pourrais définir les surfaces dans mon while(!done) et les libérer à la fin de ce while,mais je pense que cela ralentira considérablement mon programme.

    Merci

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2011
    Messages
    264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mai 2011
    Messages : 264
    Points : 448
    Points
    448

    Par défaut

    Je ne saisis pas bien: tu as un ou plusieurs signaux à afficher?

    En supposant que ce soit un signal (ce qui ressort le plus de ton explication), après avoir affiché ce signal, imaginons, de la seconde s1 à la seconde s2, dois-tu garder une trace (le jeu de mot n'est pas fait exprès) de cet affichage?

    Si je pose la question de plusieurs signaux, c'est parce que tu parles d'un sandwich de surfaces.

    Edgar.

  3. #3
    Candidat au titre de Membre du Club
    Homme Profil pro quentin rausch
    Étudiant
    Inscrit en
    juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Nom : Homme quentin rausch
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : juin 2012
    Messages : 22
    Points : 10
    Points
    10

    Par défaut

    bonjour,

    alors je vais essayer d'être un peu plus clair.
    Le programme:

    1) acquiert les données
    2) dessine mes axes. (fond noir avec dessus mon axe orthonormé = SDL_Surface)
    3) Dessine mon signal SUR ces axes.

    et ensuite on reprend la boucle à partir de 1. c'est un signal en temps réel, donc l'acquisition du signal se fait en permanence.
    Ceci suppose donc qu'à chaque nouvelle acquisition de signal (des millers par minute), le programme va me coller sur la figure précédente un nouveau background et un nouveau signal par dessus ce background.(d'où l'idée du sandwich infini)
    Et ceci prend au fur et à mesure de plus en plus de place en mémoire virtuelle.


    et au final je ne dois afficher qu'un signal. Le signal est compris dans une fenêtre de 1000pixels, donc j'affiche le signal du pixel 1 au pixel 1000 (1point = 1 pixel), puis j'applique mon background, puis sur ce background ma nouvelle acquisition,..

    donc oui je dois garder une 'trace' du signal du temps t1 au temps t1000,
    mais une fois que le temps t1000 est passé, je reviens au nouveaux temps t1.

    j'espère avoir été un peu plus clair dans mes explications.

  4. #4
    Membre Expert Avatar de Djakisback
    Inscrit en
    février 2005
    Messages
    1 974
    Détails du profil
    Informations forums :
    Inscription : février 2005
    Messages : 1 974
    Points : 2 106
    Points
    2 106

    Par défaut

    Salut,
    sans doute parce que crées une nouvelle SDL_Surface pour chaque signal (et peut-être même pour ton background) ?
    Si je comprends bien tu reçois des coordonnées/valeurs (que tu convertis ou non en coordonnées écran) et tu traces 1000 pixels maxi. Plutôt que de désallouer/réallouer dans le while, ne peux-tu pas simplement stocker une pile de 1000 coordonnées et blitter la même surface à 1000 positions différentes ?

    Si tu ne traces que des pixels, tu peux peut-être modifier directement le contenu de l'écran (jamais tenté) : http://www.friedspace.com/cprogramming/sdlpixels.php
    Vive les roues en pierre

  5. #5
    Candidat au titre de Membre du Club
    Homme Profil pro quentin rausch
    Étudiant
    Inscrit en
    juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Nom : Homme quentin rausch
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : juin 2012
    Messages : 22
    Points : 10
    Points
    10

    Par défaut

    je viens de simplifier mon programme et je pense savoir d'où vient mon problème.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    while(!done)
    {
      remplissage_de_mon_tableau_de_valeurs();
      affichage_background();
      print_signal();
     
      while(event)
      {
        tout_mes_event();
      }
     
    }
    ma fonction print_signal() est de la sorte:
    Code :
    1
    2
    3
     
    for(i=0; i<max, i++)
    line(x, tableau[i], x+1, tableau[i+1]) // qui trace une ligne entre le point de coordonnée (x, y) et (x+1, z)
    et ma fonction line() utilise déjà ma fonction putpixel qui fait ce que tu (Djakisback) m'as dit de faire (ton lien url).

    lorsque je mets ma fonction affichage_background() en commentaire, la place mémoire de mon programme reste stable et faible. une fois que je décommente, c'est parti pour une grimpette sans fin. mais sans cette fonction je superpose le nouveau signal sur l'ancien et cela devient vite un gros sac de noeuds.

    je ne crée pas de nouvelle surface SDL pour chaque signal, par contre ma fonction affiche_background() créée 11 surfaces, les blittent, et les désalloue à chaque tour de boucle. donc je ne comprends pas pourquoi cette fonction fait planter mon programme.

    concernant ceci:
    ne peux-tu pas simplement stocker une pile de 1000 coordonnées et blitter la même surface à 1000 positions différentes ?
    je pense ne pas l'avoir comprise. en fait j'ai un tableau de 10 000 valeurs (mon signal) mais je ne peux l'afficher en entier (mon écran ne fait pas 10 000pixels), du coup j'ai décidé de n'afficher que les 1000premiers, et mes event me permettent de me déplacer à l'intérieur de celui-ci. par exemple si je zoom je n'aurai plus 1000 points à afficher mais moins.

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    mai 2011
    Messages
    264
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : mai 2011
    Messages : 264
    Points : 448
    Points
    448

    Par défaut

    Puisque tu n'as qu'un signal à afficher, et en fait pas d'image à conserver, cela devrait se résumer à ceci:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #define MAX_SIGNAL_HEIGHT 780 // exemple
     
    int donnee_signal[1000];
    int done=0;
    SDL_Surface *bground=NULL;
    Uint32 couleur;
     
    while(!done) {
      acquerir_donnee(donnee_signal);
      SDL_FreeSurface(bground);
      bground=SDL_CreateRGBSurface(SDL_HWSURFACE,1000,MAX_SIGNAL_HEIGHT,32,0,0,0,0);
      prepare_background(bground);
      couleur=SDL_MapRGB(bground->format,r,g,b);
      for(i=0;i<1000;i++) setPixel(bground,i,donnee_signal[i],couleur);
      SDL_BlitSurface(bground,....);
      // traitement pour gestion arrêt par utilisateur done=1;
    }
    Pour la fonction setPixel voir ici

    Si tu veux conserver les données, fais un tableau dynamique, que tu redimensionnes au fur et mesure de tes besoins avec realloc(), mais conserver les SDL_Surfaces dans le temps est voué à l'échec, la mémoire n'étant pas extensible.

    EDIT: écrit pendant ton post !

  7. #7
    Candidat au titre de Membre du Club
    Homme Profil pro quentin rausch
    Étudiant
    Inscrit en
    juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Nom : Homme quentin rausch
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : juin 2012
    Messages : 22
    Points : 10
    Points
    10

    Par défaut

    je pense qu'il doit me manquer quelques trucs.
    Je viens juste de comprendre que SDL_FreeSurface () met le pointeur sur ma surface à NULL et ne la désalloue pas en mémoire.


    Je met donc maintenant mes SDL_Surface * en variable globale. Ce la signifie donc que je n'alloue de l'espace qu'une seule fois ? non ?

    ensuite je fais ce que vous m'avez conseillé, mais la taille mémoire de mon executable continue toujours de monter.

    qu'est ce que vous entendez par :
    conserver les SDL_Surfaces dans le temps est voué à l'échec, la mémoire n'étant pas extensible.
    actuellement elles ne sont déclarées qu'une seule fois, mise à zéro, remplies, blittées, puis remise à zéro,....

  8. #8
    Candidat au titre de Membre du Club
    Homme Profil pro quentin rausch
    Étudiant
    Inscrit en
    juin 2012
    Messages
    22
    Détails du profil
    Informations personnelles :
    Nom : Homme quentin rausch
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : juin 2012
    Messages : 22
    Points : 10
    Points
    10

    Par défaut

    Je viens de résoudre mon problème !!
    Il y avait en fait 2 problèmes, le premier était celui avec les surfaces, que vous m'avez indiqué plus haut.
    Le deuxième problème (que vous n'auriez jamais pu trouver, puisque je ne vous l'aie pas mentionné) était que je faisais
    TTF_Font * police;
    mais je ne faisais pas de TTF_CloseFont(police), ma fuite mémoire venait de là.

    Je suis soulagé, en tout cas merci de votre aide qui encore une fois m'a été très précieuse !!

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

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •