John Dogget
Messages postés384Date d'inscriptionvendredi 18 juin 2004StatutMembreDernière intervention 7 mai 2009
-
5 déc. 2007 à 14:13
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 2008
-
7 déc. 2007 à 18:38
Bonjour à tous.
J'ai ecris une function qui retourne un TStringList comme résultat, mais je n'arrive pas à liberer le StringList à la fin de la fonction sans que le programme plante
Voici cette fonction ...
function ListerProcessus:TStringList;
var
HandleCaptureProcessus:THandle;
StructureProcessus:TProcessEntry32;
Liste:TStringList;
begin
Liste:=TStringList.Create;
HandleCaptureProcessus:=CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS,0);
StructureProcessus.dwSize:=SizeOf(TProcessEntry32);
Process32First(HandleCaptureProcessus,StructureProcessus);
repeat
Liste.Add(StructureProcessus.szExeFile);
until not Process32Next(HandleCaptureProcessus,StructureProcessus);
CloseHandle(HandleCaptureProcessus);
Result:=Liste;
end;
Normalement toute StringList doit être libéré après usage, pourtant si je rajoute "Liste.Free" toute à la fin de la fonction, elle me retourne une liste vide, alors que théoriquement le résultat est déjà affecté (Result:=Liste).
Pourquoi ?
Autre chose bizarre, dans l'appel de cette fonction cette fois ...
Voila ce que j'ai ecris ...
procedure TForm2.FormShow(Sender: TObject);
var
Liste:TStringList;
IndexListe:integer;
begin
LstVw_ProcessusEnCours.Clear;
Liste:=ListerProcessus;
for IndexListe:=0 to (Liste.Count-1) do
LstVw_ProcessusEnCours.Items.Add.Caption:=Liste[IndexListe];
Liste.Free;
end;
Si je suis le code comme ça, je libere un TStringList que je n'ai jamais crée (pas de Liste.Create dans le code), pourtant ça marche très bien comme ça
Ca semble fonctionner correctement et je ça devrait me suffire mais ça me chiffonne quand même
Quelqu'un a t'il une explication ?
Result.Add(StructureProcessus.szExeFile);
Until Not
Process32Next(HandleCaptureProcessus,StructureProcessus);
CloseHandle(HandleCaptureProcessus);
End ;
<center>Highlighted with Pas2HTML </center>
Qand tu fais :
Liste : = ListerProcessus;
C'est "ListerProcessus" qui se charge de créer la StringList
et il est donc tout à fait normal que tu la libère après sont utilisation
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 6 déc. 2007 à 02:15
procedure ListerProcessus(Strings: TStrings);
var
THSHnd : THandle;
ProcEntry : TProcessEntry32;
begin
if not assigned(Strings) then
raise Exception.Create('Erreur interne: Objet en entrée non alloué.');
THSHnd := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if THSHnd <> -1 then
begin
try
Strings.BeginUpdate;
try
ProcEntry.dwSize := SizeOf(TProcessEntry32);
if Process32First(THSHnd, ProcEntry) then
repeat
Strings.Add(ProcEntry.szExeFile);
until not Process32Next(THSHnd,ProcEntry);
finally
Strings.EndUpdate;
end;
finally
CloseHandle(THSHnd);
end;
end
else
raise Exception.CreateFmt('Erreur interne (%d): Handle invalide.',[GetLastError]);
end;
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 20083 6 déc. 2007 à 19:32
Ahh ce bon f0xi ! Toujours aussi fâché avec les méthodes retournant un objet !
M'enfin, ton code est plus sécurisé que la version originale de john, c'est donc pour la bonne cause !
Vous n’avez pas trouvé la réponse que vous recherchez ?
John Dogget
Messages postés384Date d'inscriptionvendredi 18 juin 2004StatutMembreDernière intervention 7 mai 2009 6 déc. 2007 à 19:43
Perso, j'ai repris la méthode de cirec, assez similaire à la mienne, mais plus claire pour la compréhension.
C'est vrai aussi que je suis passé (volontairement) à côté des erreurs éventuelles ...
japee
Messages postés1727Date d'inscriptionvendredi 27 décembre 2002StatutModérateurDernière intervention 6 novembre 20218 7 déc. 2007 à 08:42
Florenth > perso je préfère passer l'objet en paramètre, ça évite d'oublier de le libérer après l'appel.
John Dogget > la méthode de f0xi n'est pas plus difficile à comprendre que celle de Cirec. Seule l'approche diffère :
- méthode Cirec : il faut libérer la méthode après son appel,
- méthode f0xi : il suffit de passer un objet de type TStrings en
paramètre (TListBox.Items par exemple). Plus vérification de la
validité du handle avec CreateToolHelp32Snapshot différent de -1, et
protection "béton" du code. Pourquoi dans ces conditions ne pas valider
la réponse ?
Cirec
Messages postés3833Date d'inscriptionvendredi 23 juillet 2004StatutModérateurDernière intervention18 septembre 202250 7 déc. 2007 à 11:35
hep hep hep,
c'est pas ma fonction, c'est celle de John Dogget ...
je lui ai juste montré qu'il pouvait se passer de déclarer & créer une nouveau StringList, il suffisait d'utiliser Result correctement et rien d'autre.
Ensuite il n'y a pas de différence entre une procedure avec un objet en paramètre et fonction qui renvoie un objet :
Dans les deux cas l'objet sera libéré soit automatiquement par Delphi dans le cas cité par Japee soit manuellement par l'utilisateur après utilisation
Supposez que pour x raison on ne veuille pas d'un composant visuel (ComboBox, ListBox etc) mais simplement d'une TStringList je ne crois pas qu'avec la procédure de F0xi l'on puisse se passer de libérer l'objet en fin d'utilisation.
Supposez que l'objet en question soit un TBitmap pensez vous que la procédure vous évitera de le libérer après utilisation ?
Sûr que non
C'est quand même bizarre cette amnésie que beaucoup de gens ont quand on utilise une fonction que l'on fait soit même et cette même amnésie disparait quand on utilise une fonction de Delphi ou Windows ????
Il n'y a donc pas plus intérêt d'utiliser l'une ou l'autre ... le tout est de savoir ce qu'il faut faire et quand.
Et je vous rappel que la question portait sur une fonction renvoyant un Objet et non sur une procédure utilisant un objet
Et à titre d'information si CreateToolHelp32Snapshot renvoi INVALID_HANDLE_VALUE la fonction ne plante pas pour autant et ne déclenche pas d'erreur
florenth
Messages postés1023Date d'inscriptiondimanche 1 août 2004StatutMembreDernière intervention17 août 20083 7 déc. 2007 à 18:38
Object function powaaa !
Sérieusement, je veux bien comprendre que la fonction incite plus à "oublier" de libérer mais de là à généraliser, il en va autrement. y'a des fois où c'est imparable ce genre de fonction (dans la VCL, y'en a pas mal).
Bref, ça doit sûrement être un préjugé delphiste....