[BCC++ 6.0] suppression d'une TStringGrid dynamique

suppression d'une TStringGrid dynamique [BCC++ 6.0] - C++ - Programmation

Marsh Posté le 17-10-2004 à 22:30:49    

Bonjour,
    J'essaie depuis plusieurs jours de trouver une solution à mon problème:
    Je crée une StrinGrid dynamiquement avec la commande:
       

Code :
  1. TStringGrid *Grille = new TStringGrid(TForm1);


    Ensuite je l'initialise et permet de l'éditer.
    Si je supprime "Grille" avec la commande:
       

Code :
  1. delete Grille;


    sans y avoir apporter de modification, tout se passe normalement et la StringGrid disparait de la fenêtre "Form1". Mais si entre la création et le "delete" j'ai édité la grille, même sans y avoir entré de données, une exception "EAccess Violation" dans le module VCL60.bpl est déclenchée.
    Le programme est développé sous windows XP. avec Borland C++ Builder 6.0  
    Je n'arrive pas à déterminer ce qui la provoque.  
    Avez-vous une idée de l'origine de ce problème ?
 
 

Reply

Marsh Posté le 17-10-2004 à 22:30:49   

Reply

Marsh Posté le 18-10-2004 à 01:40:08    

REMARQUE LIMINAIRE
--------------------------------
Si tu utilises le code:
TStringGrid* Grille = new TStringGrid(TForm1);
ça choque un peu...
mais je suppose que tu sous-entendais:
TStringGrid* Grille = new TStringGrid(Form1);
Form1 est de type TForm1*
 
PAR AILLEURS
--------------------------------
Ton:
TStringGrid* Grille = new TStringGrid(Form1);
est suspect en soi car c'est visiblement une déclaration LOCALE (à cause de la présence de TStringGrid*)...
 
Hypothèse: tu as peut-être un membre Grille de type TStringGrid* déclaré dans la classe TForm1, et un "homonyme" Grille déclaré par ton instruction, localement, dans la méthode qui crée ta grille. Auquel cas tu voulais dire en fait:
Grille = new TStringGrid(Form1);
(sachant que Grille est un membre déclaré).
 
J'imagine que ça peut causer un certain merdier au moment du delete (considérant qu'il est très improbable que le delete(Grille) soit situé dans la même méthode donc dans la même portée).
 
SINON
--------------------------------
Sachant que le composant "Owner" de Grille (à savoir Form1 si la construction se fait via
Grille = new TStringGrid(Form1);) est investi de la capacité d'agir sur (voire de détruire) la grille, il faut peut-être regarder dans le code si Form1 ne tente pas une action insoupçonnée sur Grille APRES ton delete...
 
En même temps, j'avoue que ça n'explique pas pourquoi ça planterait seulement quand tu édites la grille, mais c'est très probablement l'effet collatéral d'un bug beaucoup plus profond...

Reply

Marsh Posté le 18-10-2004 à 12:15:17    

D'accord avec toi, le TForm1 passé à la création est très bizarre.
Normalement lors du delete le parent est mis au courant de la suppression de l'élément, donc pas de problème à ce niveau il me semble.


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 18-10-2004 à 13:24:16    

D'abord merci de m'avoir répondu.
     Effectivement le Owner est bien Form1.
     En fait le programme d'origine défini un TStringGrid* (grille) et un TTabSheet qui sont encapsulés chacun dans un vector différent.  
     Lors des "delete", j'ai un EAccess violation au moment de supprimer la grille. Mais si je detruit uniquement sa référence dans le "vector" et "delete" le TTabSheet, le programme se déroule sans anomalie apparente.  
     Comme j'ai un doute sur la libération de l'objet TStringGrid, j'ai fait un essai avec un programme plus simple avec uniquement une "TForm"
et un "TStringGrid" où Grille est déclarée dans le fichier d'entêtes de la fiche Form1. Et je me retrouve avec la même exception.
     La vraie question maintenant est de savoir si la suppression du "Owner" suffit à libérer le composant fils.
     

Reply

Marsh Posté le 18-10-2004 à 14:01:30    

videaste95 a écrit :

...
La vraie question maintenant est de savoir si la suppression du "Owner" suffit à libérer le composant fils.


A ce que je sache, c'est le principe même du Owner d'assumer, au moment opportun, la destruction et la libération des composants qu'il possède.

Reply

Marsh Posté le 18-10-2004 à 16:35:05    

videaste95 a écrit :


     Lors des "delete", j'ai un EAccess violation au moment de supprimer la grille. Mais si je detruit uniquement sa référence dans le "vector" et "delete" le TTabSheet, le programme se déroule sans anomalie apparente.


 
:??: j'ai pas tout compris là. Tu détruirais pas deux fois ton truc justement ?


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 18-10-2004 à 21:42:03    

antp a écrit :

:??: j'ai pas tout compris là. Tu détruirais pas deux fois ton truc justement ?


Peut-être? Je n'arrive pas à savoir pouquoi la séquence:

Code :
  1. void __fastcall TForm1::Supprimer1Click(TObject *Sender)
  2. {
  3.   if(PageControl1->TabIndex > 0)
  4.   {
  5.     vector<TTabSheet*>::iterator Curseur = find(VOnglets.begin(), VOnglets.end(), PageControl1->ActivePage);
  6.     delete PageControl1->ActivePage;
  7.     VOnglets.erase(Curseur);
  8.   }
  9. }

fonctionne bien alors que la suivante plante

Code :
  1. void __fastcall TForm1::Supprimer2Click(TObject *Sender)
  2. {
  3.   if(PageControl1->TabIndex > 0)
  4.   {
  5.     TStringGrid *nGrille = (TStringGrid*) PageControl1->ActivePage->Controls[0];
  6.     vector<TStringGrid*>::iterator iGrille = find(VGrilles.begin(), VGrilles.end(), nGrille);
  7.     VGrilles.erase(iGrille);
  8.   }
  9. }

si je tente un « delete nGrille; » avant la recherche de l'iterateur. Mais le code sans le delete, comme ci-dessus, a l'air de fonctionner normalement.

Reply

Marsh Posté le 18-10-2004 à 21:52:03    

Ça m'étonnerais pas que ces listes détruisent l'objet en plus de détruire le pointeur. Il faut voir l'aide de "erase".


---------------
mes programmes ·· les voitures dans les films ·· apprenez à écrire
Reply

Marsh Posté le 20-10-2004 à 12:24:31    

videaste95 a écrit :

[la séquence plante] si je tente un « delete nGrille; » avant la recherche de l'iterateur. Mais le code sans le delete, comme ci-dessus, a l'air de fonctionner normalement.


En effet, si tu delete nGrille AVANT, je ne vois pas comment vector<TStringGrid*>::iterator iGrille = find(VGrilles.begin(), VGrilles.end(), nGrille); pourrait fonctionner (?!)
 
Pourquoi ne pas le deleter APRES?

Reply

Marsh Posté le 21-10-2004 à 18:20:53    

ACut a écrit :

En effet, si tu delete nGrille AVANT, je ne vois pas comment vector<TStringGrid*>::iterator iGrille = find(VGrilles.begin(), VGrilles.end(), nGrille); pourrait fonctionner (?!)
 
Pourquoi ne pas le deleter APRES?


    Oui, Aujourd'hui je ne sais plus exactement tout ce que j'ai tenté. Mais n'importe comment, c'est au delete nGrille que l'exception est montée. L'instruction suivante n'était même pas exécutée.
    Je remercie tous ceux qui m'ont répondus.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed