Votre question

[c++] surcharge de mémoire ?

Tags :
  • Mémoires
  • Programmation
Dernière réponse : dans Programmation
11 Juillet 2007 20:58:16

Bonjour j'utilise les librairie SDL et FMod en c++, je suis sous windows et compile avec dev c++:
Je compile ce programme mais au bout d'une dizaine de seconde il ne fonctionne plus correctement et met 4 ans a s'éteindre.
J'ai donc penser a une surcharge de la mémoire vive, mais a vrai dire je ne vois pas où dans mon code cela peut foirer ( je suis plutot débutant ... ).

Voici mon code:


  1. #include <SDL/SDL.h>
  2. #include <fmod/fmod.h>
  3. #include <fmod/fmod_errors.h>
  4. #include <stdlib.h>
  5. #include <string>
  6.  
  7.  
  8.  
  9. SDL_Rect rect_table;
  10. SDL_Surface *surf_table;
  11. SDL_Surface *Screen;
  12. SDL_Event event;
  13.  
  14. FSOUND_STREAM *music1;
  15. FSOUND_STREAM *music2;
  16. FSOUND_STREAM *music3;
  17. FSOUND_STREAM *music4;
  18. FSOUND_STREAM *music5;
  19. FSOUND_STREAM *music6;
  20. FSOUND_STREAM *music7;
  21. FSOUND_STREAM *music8;
  22.  
  23. int volume=150;
  24. int canal;
  25. std::string dossier="canaux/";
  26. //--------------------------------
  27. void initLib()
  28. {
  29. FSOUND_Init(44100,8,0);
  30. SDL_Init(SDL_INIT_VIDEO);
  31. Screen = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE);
  32. SDL_WM_SetCaption ("SDL", NULL);
  33.  
  34. }
  35. void initSon()
  36. {
  37. music1 = FSOUND_Stream_Open((dossier+"canal1.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  38. music2 = FSOUND_Stream_Open((dossier+"canal2.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  39. music3 = FSOUND_Stream_Open((dossier+"canal3.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  40. music4 = FSOUND_Stream_Open((dossier+"canal4.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  41. music5 = FSOUND_Stream_Open((dossier+"canal5.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  42. music6 = FSOUND_Stream_Open((dossier+"canal6.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  43. music7 = FSOUND_Stream_Open((dossier+"canal7.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  44. music8 = FSOUND_Stream_Open((dossier+"canal8.mp3").c_str(),FSOUND_LOOP_NORMAL,0,0);
  45.  
  46. FSOUND_Stream_Play(1,music1);
  47. /*FSOUND_Stream_Play(2,music2);
  48. FSOUND_Stream_Play(3,music3);
  49. FSOUND_Stream_Play(4,music4);
  50. FSOUND_Stream_Play(5,music5);
  51. FSOUND_Stream_Play(6,music6);
  52. FSOUND_Stream_Play(7,music7);
  53. FSOUND_Stream_Play(8,music8);*/
  54.  
  55. }
  56.  
  57. void affichage()
  58. {
  59. SDL_FillRect(Screen, NULL, 0);
  60. SDL_BlitSurface(surf_table, NULL,Screen, &rect_table);
  61. SDL_Flip(Screen);
  62. surf_table = SDL_LoadBMP("images/table.bmp");
  63.  
  64. }
  65. void deinit ()
  66. {
  67. FSOUND_Stream_Close(music1);
  68. FSOUND_Stream_Close(music2);
  69. FSOUND_Stream_Close(music3);
  70. FSOUND_Stream_Close(music4);
  71. FSOUND_Stream_Close(music5);
  72. FSOUND_Stream_Close(music6);
  73. FSOUND_Stream_Close(music7);
  74. FSOUND_Stream_Close(music8);
  75. FSOUND_Close();
  76. exit(0);
  77. }
  78. //--------------------------------
  79. void input()
  80. {
  81. if(SDL_PollEvent(&event))
  82. {
  83.  
  84. switch(event.type)
  85. {
  86. case SDL_KEYDOWN:
  87.  
  88. switch(event.key.keysym.sym)
  89. {
  90. case SDLK_p:if (volume<250){volume=volume+10;FSOUND_SetVolume(FSOUND_ALL,volume);}break;
  91. case SDLK_m:if (volume>0){volume=volume-10;}FSOUND_SetVolume(FSOUND_ALL,volume);break;
  92. }
  93. break;
  94. case SDL_KEYUP:
  95. switch(event.key.keysym.sym)
  96. {
  97.  
  98. case SDLK_ESCAPE:deinit();break ;
  99.  
  100. }
  101. break;
  102.  
  103. default: break;
  104. }
  105.  
  106. }
  107. }
  108.  
  109.  
  110. //--------------------------------
  111. int main(int argc, char **argv)
  112. {
  113. initLib();
  114. initSon();
  115.  
  116. //--------------------------------
  117. while (true)
  118. {
  119.  
  120. SDL_Event event;
  121. if (SDL_PollEvent (&event) && event.type==SDL_QUIT)break;
  122. affichage();
  123. input();
  124. }
  125. //--------------------------------
  126. }

Autres pages sur : surcharge memoire

11 Juillet 2007 21:13:01

J'ai remarquer une nette amélioration lorsque j'enlevais la ligne:
'if (SDL_PollEvent (&event) && event.type==SDL_QUIT)break;'
C'est d'ailleur la seule ligne de mon programme que je ne comprend pas et je pense que c'est le coeur de mon probleme.
Quelqu'un saurait il m'expliquer ce que c'est ?
11 Juillet 2007 22:31:00

salut,
je connais pas beaucoup SDL, mais d'après ce que je vois dans le prog, charger un bmp à chaque boucle sans vider celui d'avant, ca doit pas lui faire beaucoup de bien :) 
Contenus similaires
a b L Programmation
11 Juillet 2007 22:49:06

SDL_PollEvent c'est pour récupérer un évènement (souris clavier par exemple).
Dès qu'un évènement est lancé, la fonction se débloque et continue. C'est alors que tu traite l'évènement qui est renvoyé en paramètre.

Dans ton code, tu utilises 2 fois SDL_PollEvent (dans le main et input).
Enlève celui qui est dans "input", et fait passer le event en paramètre de input (par pointeur, pas par valeur !).
11 Juillet 2007 23:50:23

Woua diou j'avais préciser débutant !
En tout cas merci bcp, vos deux réponses vont m'aider je fais quelques bricoles et vous répond ensuite merci encore !
12 Juillet 2007 00:09:59

Ouais j'ai donc un peu regarder:
J'ai donc déclarer 2 fois: SDL_Event event;

Apres je dois t'avouer avoir une notion tres vague des pointeurs, j'ai lu des trucs dessus sur internet mais n'est pas super bien compris... Par contre je comprend ce que tu veux dire, au lieu dans l'input de faire une condition en trop je peux l'enlever, et juste importer la valeur de event a chaque fois que j'appelle justement input (?).
Ma question est donc comment puis-je rendre event, pointeur ? ( parce que en tant que valeur, et sans la condition ca marche pas mal ) et comment je le fais passer en parametre ?


Ensuite faut-il liberer mon image avec SDl ?

Et pour finir, que veut dire "if (SDL_PollEvent (&event) && event.type==SDL_QUIT)break;"

En tout cas merci pour vos réponse je progresse bien plus vite comme ca !
a b L Programmation
12 Juillet 2007 19:53:05

* Les pointeurs ne sont que des adresses mémoire.
La mémoire d'un PC (la RAM), n'est qu'une suite d'octets numérotés de 0 à beaucoup (on va dire par exemple 2^32). Ce numéro s'appelle une adresse mémoire. Quand tu écrit une variable (un "int" par exemple, avec la valeur 30), tu écris sur 4 octets dans un endroit en mémoire réservé par l'OS. Cet endroit, c'est à une adresse mémoire déterminée par l'OS (par exemple, au hasard, sur l'octet n°200000).
donc lorsque tu manipules ton "int", tu manipules la valeur (30). Lorsque tu manipules son pointeur "int *", tu manipule une adresse mémoire. En fait un pointeur c'est juste le numéro de l'adresse mémoire utilisée.
pour déclarer un pointeur, il faut ajouter une étoile, pour indiquer que c'est un type "adresse mémoire" et pas le type même:
  1. void input(SDL_Event * event)


Lorsque tu as une variable que tu manipule par valeur, il faut utiliser le "&variable" pour en récupérer l'adresse. Lorsque tu as un pointeur (donc une adresse mémoire), il faut utiliser "*variable_pointeur" pour récupérer le contenu de l'adresse mémoire (la valeur).
  1. input(&event);


Pourquoi passer par des pointeur et pas directement la valeur ? C'est simple. En C, lorsque qu'on fait passer une variable par valeur, le programme fait une copie de cette valeur en mémoire (la copie a donc une nouvelle adresse mémoire). Donc, lorsqu'on modifie la copie, on ne modifie pas l'original. Lorsqu'on passe l'adresse mémoire en paramètre, on est sûr de toucher à la valeur originale. Dans le cas du SDL, mieux vaut passer la structure par pointeur, car on ne sait pas forcément comment SDL gère le type SDL_Event.

"if (SDL_PollEvent (&event) && event.type==SDL_QUIT)break;"
c'est équivalent à ceci:
retour = SDL_PollEvent (&event); /* Fonction qui se débloque sur un nouvel évenement souris ou clavier et retourne une valeur non nulle lorsqu'il y a effectivement un évènement (ça pourrait être une erreur) */
if (retour && event.type==SDL_QUIT) /* Teste si un évènement a bien été reçu et si c'est une évènement indiquant que le programme doit se terminer (par exemple quand on clique sur la croix d'une fenêtre) */
break; /* Arrête la boucle infinie, donc ça sort de la boucle, le programme continue son exécution, arrive à la fin du main, et donc le programme s'arrête */

Ceci est obligatoire, car tu fais une boucle infinie (avec le while(1)), et donc pour terminer le programme, il faut arrêter la boucle (c'est bête un ordinateur, et ça le restera toujours :D  ).

Citation :
Ensuite faut-il liberer mon image avec SDl ?

Oui, ça libère de la mémoire. Supprime là si ton programme se termine (c'est-à-dire après la boucle infinie). Et si jamais, à un moment, tu es sûr de ne plus utiliser cette image (comme par exemple, dans un jeu où l'on changerait de niveau), alors il faut la libérer. S'il y a trop de mémoire, ça peut faire ralentir ton processus (surtout si ça tourne sous windows :D  ), alors il ne faut pas négliger le fait de librer une ressource qui n'est plus utilisée.
12 Juillet 2007 22:01:11

Ok merci pour l'explication, mais ce changement me pose probleme. Primo,
SDL_Event * event, il aime pas, en fait il ne reconnais plus "event" ducoup j'ai des erreurs du type:`type' has not been declared. dans la fonction input. Deplus, ici je déclare "event" dans la fonction input ducoup il ne sait plus ce qu'est "event" dans la main !
J'ai donc du rater qqch ...
a b L Programmation
12 Juillet 2007 22:40:31

sinon enlève ta variable locale du main et n'utilise que la variable globale.
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS