Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SDL
SDL Forum d'entraide sur l'API SDL. Avant de poster -> FAQ SDL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 01/08/2012, 17h05   #1
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : 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
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/08/2012, 00h29   #2
edgarjacobs
Membre éclairé
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 206
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 53
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 206
Points : 326
Points : 326
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.
edgarjacobs est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/08/2012, 10h31   #3
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : 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
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.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/08/2012, 13h11   #4
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 914
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 914
Points : 1 840
Points : 1 840
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
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 02/08/2012, 15h25   #5
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : 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
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:
Citation:
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.
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/08/2012, 15h27   #6
edgarjacobs
Membre éclairé
 
Homme
Développeur informatique
Inscription : mai 2011
Messages : 206
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 53
Localisation : Belgique

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2011
Messages : 206
Points : 326
Points : 326
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 !
edgarjacobs est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 02/08/2012, 16h34   #7
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : 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
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 :
Citation:
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,....
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/08/2012, 17h14   #8
limprid
Candidat au titre de Membre du Club
 
Homme quentin rausch
Étudiant
Inscription : 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
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 !!
limprid est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 03h34.


 
 
 
 
Partenaires

Hébergement Web