Commentaires

Le problème réside dans les allocations mémoire réalisées au début de la fonction main sans qu'aucune désallocation ne doit réalisée.

La solution consiste à ajouter toutes les instructions de désallocation nécessaires.
De façon pratique, compte tenu du fonctionnement de GLUt, les pointeurs issus des allocations de mémoire sont stockés au moyen de variables globales de façon à ce qu'il soit possible de les utiliser pour les appels de fonction de désallocation (static char **t dans la solution ci-dessous). Le mode de sortie normale du programme consiste à utiliser un appel à la fonction void exit(int) qui a pour conséquence l'interruption du programme avec le code d'erreur entier passé en paramètre (utilisé dans la solution ci-dessous dans la fonction keyboard en réponse à l'utilisation de la touche de fonction escape). L'utilisation de la fonction void atexit(void (*f)(void)) permet de programmer l'exécution de la fonction f par la fonction exit avant que celle-ci n'interrompe le programme. Dans notre situation, la fonction f pourra assurer le rôle de ramasse miettes (garbage collector). Dans le programme ci-dessous, la fonction f a été nommée clean et effectue toutes les désallocations de mémoire manquantes.

L'exécutable

Fichier source : TestMemoireSolution.cpp

/* Test allocations/desallocation memoire       */
/*                                              */
/* Auteur: Nicolas JANEY                        */
/* nicolas.janey@univ-fcomte.fr                 */
/* Mars 2020                                    */

#if defined(WIN32) || defined(WIN64)
  #define _CRTDBG_MAP_ALLOC
  #if defined(_DEBUG)
    #define _AFXDLL
    #include <afx.h>
  #endif
#endif
#include <stdlib.h>
#if defined(WIN32) || defined(WIN64)
  #include <crtdbg.h>
#endif

#include <stdio.h>
#include <math.h>

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>

static char **t;

/* Fonction executee lors d'un rafraichissement */
/* de la fenetre de dessin                      */

static void display(void) {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glutSwapBuffers();
  int error = glGetError();
  if ( error != GL_NO_ERROR )
    printf("Erreur OpenGL: %d\n",error);
}

/* Fonction executee lors de la frappe          */
/* d'une touche du clavier                      */

static void keyboard(unsigned char key,int x,int y) {
  switch ( key ) {
    case 0x1B :
      exit(0); 
      break; }
}

static void clean() {
  for ( int i = 0 ; i < 100 ; i++ )
    free(t[i]);
  free(t);
}

/* Fonction principale                          */

int main(int argc,char **argv) {

#if defined(WIN32) || defined(WIN64)
  #if defined(_DEBUG)
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
   // _crtBreakAlloc = 120;
  #endif
#endif

  atexit(clean);

  t =(char **) calloc(100,sizeof(char *));
  for ( int i = 0 ; i < 100 ; i++ )
    t[i] =(char *) malloc(1000);

  glutInit(&argc,argv);
  glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  glutInitWindowSize(400,300); 
  glutInitWindowPosition(50,50); 
  glutCreateWindow("Test allocations/désallocation mémoire"); 
  glutKeyboardFunc(keyboard);
  glutDisplayFunc(display);
  glutInitWindowPosition(250,100);
  glutMainLoop();
  return(0);
}

RETOUR