Bonjour,
Je suis en Delphi 2006 Win32 sous XP et W7.
J'ai créé un descendant de TXMLDocument (qui répond au doux nom de TBackToDrawerParamXMLDoc) que j'utilise dans deux projets différents.
Dans l'un des deux, le TBackToDrawerParamXMLDoc est créé avec, pour propriétaire, une TForm, et tout se passe bien.
Dans l'autre projet, TBackToDrawerParamXMLDoc est créé localement dans une fonction avec un propriétaire à Nil (TBackToDrawerParamXMLDoc.Create(Nil) ), et là, à l'appel d'une première méthode (qui récupère simplement la valeur d'un attribut d'un noeud), il passe directement dans le destructeur de TBackToDrawerParamXMLDoc ....
Du coup, dans le FreeAndNil en fin de procédure, boum : opération de pointeur incorrect !
Après lecture de la doc Delphi 2006, reproduite ci-dessous (et un peu d'aspirine) :
Il semblerait que l'on soit dans ce cas. Les experts de cet honorable forum peuvent-ils me le comfirmer ? Et si oui comment faire pour contourner ce problème.Les composants TXMLDocument créés lors de l'exécution sans propriétaire sont libérés automatiquement lorsque toutes les références à leur interface IXMLDocument sont libérées. Cela constitue une différence avec les composants TXMLDocument ajoutés à une fiche ou un module de données lors de la conception ou ceux créés avec un propriétaire. Lorsqu'il est ajouté à une fiche ou un module de données lors de la conception, l'objet est libéré explicitement par son Owner (la fiche ou le module de données
Pour info, ci-dessous, le code de ma fonction (PREFIX_CATEGORY et PREFIX_RESULT sont des constantes)
D'avance merci
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 function RelectureDemandee(UneCategorieTest: Integer ; UnCodeResultat, UnCodeResultatEx, UnCodeResultatMS8001: Integer): Boolean; var BackToDrawerParamXMLDoc : TBackToDrawerParamXMLDoc; // classe pour stockage des resultats par categorie NodeName : string; // nom reconstitué du noeud à partir du numéro de la catégorie AttribName : string; // nom reconstitué de l'attribut à partir du numéro du résultat XmlNode : IXmlNode; begin Result := False; NodeName := TBackToDrawerParamXMLDoc.PREFIX_CATEGORY + IntToStr(UneCategorieTest); AttribName := TBackToDrawerParamXMLDoc.PREFIX_RESULT + IntToStr(UnCodeResultatEx); BackToDrawerParamXMLDoc := TBackToDrawerParamXMLDoc.Create(Form2); BackToDrawerParamXMLDoc.XML.Clear; try BackToDrawerParamXMLDoc.XML.Add('<?xml version="1.0"?><BackToDrawerParams></BackToDrawerParams>'); BackToDrawerParamXMLDoc.Active := True; XmlNode := BackToDrawerParamXMLDoc.DocumentElement as IXmlNode; if BackToDrawerParamXMLDoc.GetAttributeValue(XmlNode, NodeName, AttribName) = 'O' then Result := True; finally FreeANdNil(BackToDrawerParamXMLDoc); end; end;
Kim
Partager