Fuite de mémoire ? Pourquoi ? [Résolu]

Signaler
Messages postés
149
Date d'inscription
jeudi 22 avril 2004
Statut
Membre
Dernière intervention
10 décembre 2009
-
Messages postés
149
Date d'inscription
jeudi 22 avril 2004
Statut
Membre
Dernière intervention
10 décembre 2009
-
Bonjour à tous

Pour tester un problème rencontré dans une de mes applis j'ai créé une autre petite appli et mis le code suivant exécuté dans un timer.

Il ne fait qu'allouer un grand nombre de pointeurs pour les libérer immédiatement mais présente le même problème rencontré dans lautre appli.

Voilà mon soucis:
J'affiche le gestionnaire de programme Windows et affiche les processus.

Si je ne touche à rien pendant le fonctionnement tout va bien :
Le programme alloue et libère bien la mémoire:
après le pic je retombe toujours sur la mémoire utilisée au démarrage...

Mais si je provoque des événements windows (ex: survol de la barre de tache, clic sur le menu démarrer, ouverture d'un dossier, déplacement d'une fenêtre)
mon programme se met à utiliser plus de mémoire : je ne retombe plus sur la valeur au démarrage (+4ko, +8ko et plus parfois)
A la longue ça finit par faire beaucoup

A quoi est-ce dù et quelqu'un a t'il déjà rencontré ce problème ?

Voilà le code de test (j'utilise C++ builder v 5)

"
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
   static int iter=0;
   static int nberr=0;

   long *ordre;
   char **listOfItem=0;
   int nbelts = 1000000;      //1 000 000 ouf!
   int erreur = 0;
   bool memok;

   memok = true;

   listOfItem = NULL;
   ordre = NULL;

   try
   {
      if (memok)
         ordre = new long[nbelts ];         // max de nb éléments
      memok = memok & (ordre != NULL);

      if (memok)
         listOfItem = new char*[nbelts ];   // max de nb éléments
      memok = memok & (listOfItem != NULL);

      if (memok)
      {
         //Affectation des pointeurs
         for (int i=0; i<nbelts ; i++)
            listOfItem[i] = NULL;

         for (int i=0; i<nbelts; i++)
         {
            listOfItem[i] = new char[256];
            if ( listOfItem[i] != NULL )
               memset(listOfItem[i], 0, 256);
            else
            {
               memok = false;
               for (int i=i-1; i>=0; i--)
               {
                  if (listOfItem[i] != NULL)
                  {
                     delete [] listOfItem[i];
                     listOfItem[i] = NULL;
                  }
               }
               if (listOfItem != NULL)
               {
                  delete [] listOfItem;
                  listOfItem = NULL;
               }
               if (ordre != NULL)
               {
                  delete [] ordre;
                  ordre = NULL;
               }
               nbelts = 0;
               erreur = 1;
            }
         }
      }
   }
   catch (Exception &exception)
   {
      memok = false;
   }

   //Libération des pointeurs

   if (listOfItem != NULL)
   {
      for (int i=nbelts-1; i>=0; i--)
      {
         if (listOfItem[i] != NULL)
            delete [] listOfItem[i];
      }
      delete [] listOfItem;
   }

   if (ordre != NULL)
      delete [] ordre;

   if (! memok)
      nberr++;

   iter++;
   Edit1->Text = AnsiString(iter);

   Edit2->Text = AnsiString(nberr);
}
"

Si quelqu'un peut éclairer ma lanterne.

D'avance Merci

PS: j'ai essayé de faire un "catch (std::bad_alloc &e)"
mais le compilo me dit que "bad_alloc" ne fait pas partie de std (???).
De toute façon quand l'exception se produit le programme ne libère pas la mémoire et se vautre lamentablement (ex:   avec int nbelts = 10 000 000)
on crashe et fin du voyage (abnormal program termination)

4 réponses

Messages postés
149
Date d'inscription
jeudi 22 avril 2004
Statut
Membre
Dernière intervention
10 décembre 2009

Bonjour à tous !

ben finalement la fuite venait de ma gestion des événements windows
Un break manquant dans une boucle de recherche d'un indice et hop ! accès après la fin d'un tableau...

L'agriculture a besoin de bras. Je devrais peut être m'inscrire sur les listes !
Messages postés
338
Date d'inscription
samedi 9 août 2003
Statut
Membre
Dernière intervention
9 juillet 2011
2
petit probleme ici

for (int i=i-1; i>=0; i--)

i ne peux pas etre valoir i-1  car i ne vaux rien encore
// tu devrai verifier si le i est celui de ta premiere boucle ou celui que tu tentes d'initialiser.
Messages postés
149
Date d'inscription
jeudi 22 avril 2004
Statut
Membre
Dernière intervention
10 décembre 2009

Salut gamemonde

Merci pour ta réponse.
Effectivement il y a avait un problème, c'était pas très propre...
J'ai rectifié mais mon prog joue toujours la passoire dès que je "bouge" une oreille (enfin, je veux dire quand j'interagis avec le bureau )

"void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
   static int iter=0;
   static int nberr=0;

   long *ordre;
   char **listOfItem=0;
   long nbmax = 1000000;            //1 000 000
   long nbitems;
   bool memok;

   memok = true;

   listOfItem = NULL;
   ordre = NULL;
   nbitems=0;

   try
   {
      if (memok)
         ordre = new long[nbmax];         // max de nb éléments
      memok = memok & (ordre != NULL);

      if (memok)
         listOfItem = new char*[nbmax];   // max de nb éléments
      memok = memok & (listOfItem != NULL);

      if (memok)
      {
         //Affectation des pointeurs
         for (int i=0; i<nbmax; i++)
            listOfItem[i] = NULL;

         for (int i=0; i<nbmax; i++)
         {
            listOfItem[i] = new char[256];
            if ( listOfItem[i] != NULL )
            {
               memset(listOfItem[i], 0, 256);
               nbitems++;
            }
            else
            {
               memok = false;
               for (int i=0; i<nbitems; i++)
               {
                  if (listOfItem[i] != NULL)
                  {
                     delete [] listOfItem[i];
                     listOfItem[i] = NULL;
                  }
               }
               if (listOfItem != NULL)
               {
                  delete [] listOfItem;
                  listOfItem = NULL;
               }
               if (ordre != NULL)
               {
                  delete [] ordre;
                  ordre = NULL;
               }
               nbitems = 0;
            }
         }
      }
   }
   catch (...)
   {
      memok = false;
   }

   //Libération des pointeurs

   if (listOfItem != NULL)
   {
      for (int i=0; i<nbitems; i++)
      {
         if (listOfItem[i] != NULL)
         {
            delete [] listOfItem[i];
            listOfItem[i] = NULL;
         }
      }
      delete [] listOfItem;
      listOfItem = NULL;
   }

   if (ordre != NULL)
   {
      delete [] ordre;
      ordre = NULL;
   }

   if (! memok)
      nberr++;

   iter++;
   Edit1->Text = AnsiString(iter);
   Edit2->Text = AnsiString(nberr);

 
}"
Messages postés
149
Date d'inscription
jeudi 22 avril 2004
Statut
Membre
Dernière intervention
10 décembre 2009

Arghhh!!!

J'ai confondu new et malloc.
new ne renvoie jamais NULL en cas d'erreur mais déclenche une exception:
J'ai simplifié le test. Mais toujours des pertes de mémoires lors d'événements
windows...

fonction appelée dans un Timer
bool TForm1::Test()
{
   long *ordre;
   char **listOfItem;
   long nbmax = 100000;
   long nbitems;
   bool memok;

   memok = true;
   nbitems=0;

   try
   {
      ordre = new long[nbmax];        
      listOfItem = new char*[nbmax];  
      //Affectation des pointeurs
      for (int i=0; i<nbmax; i++)
      {
         listOfItem[i] = new char[256];
         memset(listOfItem[i], 0, 256);
         nbitems++;
      }
   }
   catch (...)    //(std::bad_alloc)      //passe pas en compil: pas membre std?
   {
      memok = false;
   }

   for (int i=0; i<nbmax; i++)
      delete [] listOfItem[i];
   delete [] listOfItem;
   delete [] ordre;

   return memok;

}