Fuite de mémoire ? Pourquoi ?

Résolu
steph12358 Messages postés 149 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 10 décembre 2009 - 13 nov. 2008 à 10:55
steph12358 Messages postés 149 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 10 décembre 2009 - 18 nov. 2008 à 15:06
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

steph12358 Messages postés 149 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 10 décembre 2009 1
18 nov. 2008 à 15:06
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 !
3
gamemonde Messages postés 336 Date d'inscription samedi 9 août 2003 Statut Membre Dernière intervention 9 juillet 2011 2
13 nov. 2008 à 11:29
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.
0
steph12358 Messages postés 149 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 10 décembre 2009 1
13 nov. 2008 à 13:49
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);

 
}"
0
steph12358 Messages postés 149 Date d'inscription jeudi 22 avril 2004 Statut Membre Dernière intervention 10 décembre 2009 1
13 nov. 2008 à 15:56
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;

}
0
Rejoignez-nous