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 :

Fuite mémoire en SDL/OpenGL


Sujet :

SDL

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 28
    Par défaut Fuite mémoire en SDL/OpenGL
    Bonjour,

    Débutant en programmation C++, SDL et OpenGL, je cherche à réaliser un petit shooter 2D.

    Je constate déjà que mon tout petit programme souffre d'une fuite mémoire régulière d'environ 4ko toutes les 2 secondes. Avant que ce genre de problèmes n'enflent jusqu'à devenir ingérable, et pour bien comprendre le fonctionnement de ce langage et de ces modules, je voulais vous soumettre mes trois fonctions principales pour savoir si vous pouviez détecter ou m'aider à détecter l'origine de cette fuite.

    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
    /** The main loop. **/
    void CEngine::Start()
    {
    	m_lLastTick = SDL_GetTicks();
    	m_bQuit = false;
     
    	// Main loop: loop forever.
    	while ( !m_bQuit )
    	{
    		// Handle mouse and keyboard input
    		HandleInput();
     
    		if ( m_bMinimized ) {
    			// Release some system resources if the app. is minimized.
    			#if _WIN32
                WaitMessage(); // pause the application until focus in regained
                #endif
     
    		} else {
     
    			// Do some thinking
    			DoThink();
     
    			// Render stuff
    			DoRender();
     
    			//Attends la fin de la frame
    			SDL_Delay(1000/30 - (SDL_GetTicks() - m_lLastTick));
    		}
    	}
     
    	End();
    }
     
    /** Handles the updating routine. **/
    void CEngine::DoThink()
    {
    	long iElapsedTicks = SDL_GetTicks() - m_lLastTick;
    	m_lLastTick = SDL_GetTicks();
     
    	//Think( iElapsedTicks );
     
    	m_iFPSTickCounter += iElapsedTicks;
    }
     
    /** Handles the rendering and FPS calculations. **/
    void CEngine::DoRender()
    {
    	++m_iFPSCounter;
    	if ( m_iFPSTickCounter >= 1000 )
    	{
    		m_iCurrentFPS = m_iFPSCounter;
    		m_iFPSCounter = 0;
    		m_iFPSTickCounter = 0;
    	}
     
    	// Lock surface if needed
    	if ( SDL_MUSTLOCK( m_pScreen ) )
    		if ( SDL_LockSurface( m_pScreen ) < 0 )
    			return;
     
    	// Effacer le tampon des couleurs
    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glClearDepth(0.0f);
     
    	glLoadIdentity();
     
    	//Render( GetSurface() );
     
    	// Unlock if needed
    	if ( SDL_MUSTLOCK( m_pScreen ) )
    		SDL_UnlockSurface( m_pScreen );
     
    	// Tell SDL to update the whole gScreen
    	//SDL_Flip( m_pScreen );
    	glFlush();
        SDL_GL_SwapBuffers();
    }
    Je me suis inspiré de ce tuto pour mon moteur SDL et j'ai donc commenté l'appel aux fonctions "Think" et "Render" contenant vraiment le code de mon jeu, afin de cibler le problème.

    Merci d'avance.

    Eric 'Henn' Niubo

  2. #2
    Membre Expert Avatar de Djakisback
    Profil pro
    Inscrit en
    Février 2005
    Messages
    2 023
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 2 023
    Par défaut
    Salut,
    on peut voir le code de HandleInput() ?
    A part ça tu pourrais déclarer iElapsedTicks en static je crois.
    Sinon rien à voir mais :
    - est-ce que SDL_GL_SwapBuffers() n'inclut pas déjà un appel à glFlush() ?
    - il ne me semble pas que t'aies besoin d'appeler glClearDepth(0.0f); à chaque cycle ?
    - le lien vers ton tuto est dead ^^

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

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

    Pour le tuto, j'ai du me tromper d'adresse :
    http://wiki.gamedev.net/index.php/SD...gine_Framework

    J'ai commenté glFlush() et glClearDepth(). Tout marche encore (fuite comprise) donc effectivement les instructions devaient être redondantes. Merci pour ça.

    Sinon lorsque je commente HandleInput() et que je passe iElapsedTicks en static, la fuite continue.

    Sinon HandleInput() est comme suit:

    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
    void CEngine::HandleInput()
    {
    	// Poll for events, and handle the ones we care about.
    	SDL_Event event;
    	while ( SDL_PollEvent( &event ) )
    	{
    		switch ( event.type )
    		{
    		case SDL_KEYDOWN:
    			// If escape is pressed set the Quit-flag
    			if (event.key.keysym.sym == SDLK_ESCAPE)
    			{
    				m_bQuit = true;
    				break;
    			}
     
    			KeyDown( event.key.keysym.sym );
    			break;
     
    		case SDL_KEYUP:
    			KeyUp( event.key.keysym.sym );
    			break;
     
    		case SDL_QUIT:
    			m_bQuit = true;
    			break;
     
    		case SDL_MOUSEMOTION:
    			MouseMoved(
    				event.button.button,
    				event.motion.x,
    				event.motion.y,
    				event.motion.xrel,
    				event.motion.yrel);
    			break;
     
    		case SDL_MOUSEBUTTONUP:
    			MouseButtonUp(
    				event.button.button,
    				event.motion.x,
    				event.motion.y,
    				event.motion.xrel,
    				event.motion.yrel);
    			break;
     
    		case SDL_MOUSEBUTTONDOWN:
    			MouseButtonDown(
    				event.button.button,
    				event.motion.x,
    				event.motion.y,
    				event.motion.xrel,
    				event.motion.yrel);
    			break;
     
    		case SDL_ACTIVEEVENT:
    			if ( event.active.state & SDL_APPACTIVE ) {
    				if ( event.active.gain ) {
    					m_bMinimized = false;
    					WindowActive();
    				} else {
    					m_bMinimized = true;
    					WindowInactive();
    				}
    			}
    			break;
    		} // switch
    	} // while (handling input)
    }
    Je l'ai laissée tel que trouvée dans le tuto mais je n'utilise que les fonctions KeyUp(), KeyDown(), MouseMoved(), MouseButtonUp() et MouseButtonDown(). Elles se contentent d'accéder à des getters et des setters mais les voilà comme suit:

    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
    void CMyEngine::KeyDown(const int& iKeyEnum)
    {
        switch (iKeyEnum)
        {
        case SDLK_LEFT:
          // Left arrow pressed
          pj->dirGD(-1);
          break;
        case SDLK_RIGHT:
          // Right arrow pressed
          pj->dirGD(1);
          break;
        case SDLK_UP:
          // Up arrow pressed
          pj->dirHB(-1);
          break;
        case SDLK_DOWN:
          // Down arrow pressed
          pj->dirHB(1);
          break;
        }
    }
     
     
    void CMyEngine::KeyUp(const int& iKeyEnum)
    {
    	switch (iKeyEnum)
    	{
    	case SDLK_LEFT:
    	  // Left arrow released
    	  pj->stopGD(-1);
    	  break;
    	case SDLK_RIGHT:
    	  // Right arrow released
    	  pj->stopGD(1);
    	  break;
    	case SDLK_UP:
    	  // Up arrow released
    	  pj->stopHB(-1);
    	  break;
    	case SDLK_DOWN:
    	  // Down arrow released
    	  pj->stopHB(1);
    	  break;
    	}
    }
     
    void CMyEngine::MouseMoved(const int& iButton,
    			   const int& iX,
    			   const int& iY,
    			   const int& iRelX,
    			   const int& iRelY)
    {
    	// Handle mouse movement
     
    	// iX and iY are absolute screen positions
    	// iRelX and iRelY are screen position relative to last detected mouse movement
     
    	if (iButton == SDL_BUTTON_LEFT)
    	{
    		//Met a jour le X et Y de la cible
    		pj->setXCible(iX);
    		pj->setYCible(iY);
    	}
    }
     
    void CMyEngine::MouseButtonUp(const int& iButton,
    			      const int& iX,
    			      const int& iY,
    			      const int& iRelX,
    			      const int& iRelY)
    {
    	// Handle mouse button released
     
    	if( iButton == SDL_BUTTON_LEFT)
    	{
    		//Arrête le tir
    		pj->setCompTir(0);
    		pj->setTirActif(false);
    	}
    }
     
    void CMyEngine::MouseButtonDown(const int& iButton,
    				const int& iX,
    				const int& iY,
    				const int& iRelX,
    				const int& iRelY)
    {
    	// Handle mouse button pressed
     
    	if( iButton == SDL_BUTTON_LEFT)
    	{		
    		//Lance le compteur et le tir
    		pj->setCompTir(SDL_GetTicks());
    		pj->setTirActif(true);
    		pj->setXCible(iX);
    		pj->setYCible(iY);
    	}	
    }
    J'imagine que j'ai du faire de manière répétée une erreur assez évidente pour les spécialistes. Donc il suffira qu'on me la montre une fois et que je la trouve pour ne plus me laisser faire, mais en attendant je rame un peu...

  4. #4
    Membre Expert
    Avatar de shenron666
    Homme Profil pro
    avancé
    Inscrit en
    Avril 2005
    Messages
    2 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : avancé

    Informations forums :
    Inscription : Avril 2005
    Messages : 2 582
    Par défaut
    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
    Tutoriels OpenGL
    Je ne répondrai à aucune question en MP
    - Si c'est simple tu dis que c'est compliqué et tu le fait
    - Si c'est compliqué tu dis que c'est simple et tu le sous-traite ou le fait faire par un stagiaire.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 28
    Par défaut
    Merci,

    Désolé d'être resté absent si longtemps mais je peux me remettre à bosser sur mes projets quand je peux...

    Je vais tester le Memory Manager et répondre pour donner mes résultats.

  6. #6
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut
    J'ai moi aussi d'enormes fuites pour mon projet de jeu en SDL.

    J'ai programmé un menu. Plus je navigue dans le menu, plus j'ai des fuites de mémoire.
    Pourtant j'ai bien fait attention a libérer au fur et a mesure mes surfaces avec SDL_FreeSurface et mes pointeurs avec free.

    J'utilise valgrind, vous sauriez me dire a quoi corresponds definitely lost, possibly lost, still reachable et supressed dans LEAK SUMMARY ?

    ==15095== definitely lost: 1,250,556 bytes in 1,103 blocks.
    ==15095== possibly lost: 48,420 bytes in 8 blocks.
    ==15095== still reachable: 81,378 bytes in 1,115 blocks.
    ==15095== suppressed: 0 bytes in 0 blocks.
    Ca fait un peu mal non ?
    Bref, j'ai 6000 lignes de code ca va etre tendu a debugguer...
    j'ai compiler avec -g.

    L'options -v m'aide pas trop a trouver mes erreurs. Comment dois je faire pour voir quels sont les allocations qui ne sont pas libéré ?
    Merci d'avance

    EDIT :
    J'ai trouve un oublie de free a chaque fois que je chargeait mes boutons ^^

    Par contre maintenant j'ai constamment dans les 80k de still reachable (comme avant)

    Ca correponds a quoi still reachable ?

  7. #7
    Membre chevronné
    Inscrit en
    Août 2004
    Messages
    556
    Détails du profil
    Informations forums :
    Inscription : Août 2004
    Messages : 556
    Par défaut
    Définitivement perdu: les données alloués qui n'ont jamais été désallouées et dont plus rien ne pointe dessus. Tu peux plus jamais les récupérer.

    Possibly lost: Des données allouées qui sont probablement perdues de manière définitive. Valgrind n'arrive pas à dire si vraiment ils ont été perdus (par exemple lors de l'utilisation d'un vecteur de pointeurs)

    Still reachable: des données non libérées à la fin de ton apply mais tu as quand même des pointeurs valide dessus.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 8
    Par défaut
    bonjour,

    j'ai aussi un problème de fuite mémoire dans un programme SDL/OPENGL simple.
    Par la !!!

    si tu as des élément pour avancer je suis preneur

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 28
    Par défaut
    Donc. Je reviens à cette discussion longtemps après l'avoir créée mais le développement amateur avance au rythme où il avance...

    Le problème est résolu.

    J'ai utilisé le MemoryManager, j'ai bien tout nettoyé et je me suis rendu compte que j'avais un petit problème lorsque je fermais avec le clic...

    Mais sinon, comme je l'ai également vu sur cette autre discussion, l'impression de fuite mémoire vient de ce que la mémoire augmente de manière progressive dans la première minute où le jeu est lancé, alors qu'il est déjà en fonctionnement.

    Elle se stabilise assez vite autour de 12 Mo. Je suppose que les processus de l'ombre ont encore du boulot à ce moment là...

    Merci beaucoup, en tout cas.

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 13/03/2012, 18h55
  2. Fuites mémoires SDL ?
    Par jvh45 dans le forum SDL
    Réponses: 5
    Dernier message: 31/05/2011, 18h22
  3. SDL+opengl+drivers nvidia 56.72 et plus
    Par ttf dans le forum OpenGL
    Réponses: 2
    Dernier message: 22/05/2004, 14h28
  4. [Debutant] Sdl & OpenGl link ne marche pas
    Par Riko dans le forum OpenGL
    Réponses: 9
    Dernier message: 18/02/2004, 16h13
  5. [debug] fuites mémoires
    Par tmonjalo dans le forum C
    Réponses: 3
    Dernier message: 28/07/2003, 17h20

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