[C++]Erreur EInvalidPointer

Résolu/Fermé
Pyrox41 Messages postés 98 Date d'inscription mardi 3 juin 2008 Statut Membre Dernière intervention 25 octobre 2009 - 31 mars 2009 à 11:04
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 - 29 mai 2009 à 12:43
Bonjour,

Quand je ferme mon programme, j'ai cette erreur qui apparait. Quand je fais un debugage, il me situe l'erreur sur le exit(0) . Je ne comprends pas pourquoi l'erreur se situe ici.
Si quelqu'un peut m'aider, ce serait sympa. Je joins le code de mon programme pour vous aider à comprendre mon probleme.

Merci

Ps : Je ne savais pas trop comment inserer du code.

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Main.h"
#include <CMysql.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"

TForm1 *Form1;
CMySQL *base;
//CMySQL *base2;

AnsiString Requete;
AnsiString c,c1;
int nb_ch  ;
int nb_enr ;
int ret ;
int i ;
int j ;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
  base = new CMySQL();
  //base2 = new CMySQL();
  bool ouvert;
  //bool ouvert2;

  ouvert = base->ouvrirConnexion("127.0.0.1","Mathieu","mathieu","projets",PORT);
  if(ouvert)
  {
    Edit1->Text = "Connecté";
  }
  else
  {
    Edit1->Text = "Non Connecté";
  }

  /*ouvert2 = base->ouvrirConnexion("192.168.1.32","Francois","francois","projet2009",PORT);
  if(ouvert2)
  {
    Edit2->Text = "Connecté";
  }
  else
  {
    Edit2->Text = "Non Connecté";
  }*/
}

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  Requete.sprintf("SELECT * FROM basevisiteur");
  base->envoyerRequete(Requete.c_str());
  base->reponseRequete();

  nb_enr = base->nbEnregistrements();
  nb_ch = base->nbChamps();

  ListBox1->Clear();

  if(nb_ch == 6)
  {
    for(i = 0 ; i < nb_enr ; i++)
    {
      ret = base->recupererEnregistrement();
      if( ret == 0)
      {
        for(j = 0 ; j < nb_ch ; j++)
        {
          c1 = base->recupererColonne(j);
          c = c + c1 + " / " ;
        }
        ListBox1->Items->Add(c);
        c = "";
      }
    }
  }
  else
  {
    ListBox1->Items->Add("Nombre de champs incorrect");
  }
}
//--------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
  Requete.sprintf("SELECT * FROM basepersonnel");
  base->envoyerRequete(Requete.c_str());
  base->reponseRequete();

  nb_enr = base->nbEnregistrements();
  nb_ch = base->nbChamps();

  ListBox1->Clear();

  if(nb_ch == 4)
  {
    for(i = 0 ; i < nb_enr ; i++)
    {
      ret = base->recupererEnregistrement();
      if( ret == 0)
      {
        for(j = 0 ; j < nb_ch ; j++)
        {
          c1 = base->recupererColonne(j);
          c = c + c1 + " / " ;
        }
        ListBox1->Items->Add(c);
        c = "";
      }
    }
  }
  else
  {
    ListBox1->Items->Add("Nombre de champs incorrect");
  }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
  base->fermerConnexion();
  Edit1->Text = "Base Deconnecté";
  delete base;
  exit(0);
}
//---------------------------------------------------------------------------


8 réponses

Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
31 mars 2009 à 12:18
Salut.
Je ne comprends pas plus, mais il est possible qu'un destructeur soit mal codé.
Ou alors, quelle fonction exit utilise tu ? TForm1::exit(int) ou ::exit(int) ?
0
Pyrox41 Messages postés 98 Date d'inscription mardi 3 juin 2008 Statut Membre Dernière intervention 25 octobre 2009 6
2 avril 2009 à 11:38
Re

Merci pour ta réponse.

Après avoir étudié le problème, j'ai remarque que je fermé le programme sans faire d'opérations sur la base, il ne me mette pas l'erreur alors que si je fais une opération sur la base, il me met l'erreur EInvalidPointer. Donc je pense que le problème vient de mon pointeur base qui me sert à dialoguer avec la base de données mais je ne suis pas sur.

Pyrox41
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
2 avril 2009 à 11:57
est-ce que fermerConnexion ne détruirait pas le pointeur ?
Ce qui fait que le delete opère sur un pointeur invalide.
Essai de commenter le delete voir si le problème persiste.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
2 avril 2009 à 12:01
Pour préciser ma pensée. Sous Qt, il y a un slot deleteLater() qui envoi un signal au gestionnaire, qui se charge de détruire automatiquement l'objet.
Ce qui est possible ici, c'est qu'il se passe soit ce que j'ai dit au message précédent (mais l'erreur devrais être situé sur le delete et non sur le exit) soit un signal de destruction est bien envoyé, mais n'est pas traité tout de suite (en général pas avant la fin de la fonction) du coup tu détruit légalement le pointeur, mais lorsque tu sort de la fonction avec le exit, le gestionnaire qui essai de tuer le pointeur se retrouve avec un pointeur déjà tué.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Pyrox41 Messages postés 98 Date d'inscription mardi 3 juin 2008 Statut Membre Dernière intervention 25 octobre 2009 6
28 mai 2009 à 08:22
Re

J'ai essayé en commettant divers lignes dont les delete mais rien ne change.
Je ne comprends pas ce qui se passe. J'avais pensé à un problème logiciel ou matériel car j'utilise ses fonctions dans d'autres programmes et tout fonctionne très bien.

Qu'est que vous en pensez ?

Pyrox41
0
Pyrox41 Messages postés 98 Date d'inscription mardi 3 juin 2008 Statut Membre Dernière intervention 25 octobre 2009 6
28 mai 2009 à 08:26
Re

Bon, j'ai essayé en commentant diverses lignes dont les delete mais rien ne change

J'avais pensé à un problème logiciel ou matériel car j'utilise ses fonctions dans d'autres programmes et tout fonctionne correctement donc je ne comprends pas d'où vient mon problème..

Quand pensez vous ?

Pyrox41
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
28 mai 2009 à 12:49
Essaie de mettre des print en entré et en sortie dans tout tes destructeurs, voir si il n'y en a pas un qui plante.
Il faudrait tester, et je me répète un peux, mais si tu fait :
Class_quelconque *A=new Class_quelconque;
exit(0);
je pense que le destructeur de Class_quelconque sera appelé sur le exit(0). à un moment donné, il faut bien vidé la mémoire. Mais je surestime peut être le C++.
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
29 mai 2009 à 12:43
J'ai une autre pîste pour toi que je vien de voir dans l'aide de Qt (Object Tree and Object Ownership)
When QObjects are created on the heap (i.e., created with new), a tree can be constructed from them in any order, and later, the objects in the tree can be destroyed in any order. When any QObject in the tree is deleted, if the object has a parent, the destructor automatically removes the object from its parent. If the object has children, the destructor automatically deletes each child. No QObject is deleted twice, regardless of the order of destruction.

When QObjects are created on the stack, the same behavior applies. Normally, the order of destruction still doesn't present a problem. Consider the following snippet:

 int main()
 {
     QWidget window;
     QPushButton quit("Quit", &window);
     ...
 }
The parent, window, and the child, quit, are both QObjects because QPushButton inherits QWidget, and QWidget inherits QObject. This code is correct: the destructor of quit is not called twice because the C++ language standard (ISO/IEC 14882:2003) specifies that destructors of local objects are called in the reverse order of their constructors. Therefore, the destructor of the child, quit, is called first, and it removes itself from its parent, window, before the destructor of window is called.

But now consider what happens if we swap the order of construction, as shown in this second snippet:

 int main()
 {
     QPushButton quit("Quit");
     QWidget window;

     quit.setParent(&window);
     ...
 }
In this case, the order of destruction causes a problem. The parent's destructor is called first because it was created last. It then calls the destructor of its child, quit, which is incorrect because quit is a local variable. When quit subsequently goes out of scope, its destructor is called again, this time correctly, but the damage has already been done.
0