Manipulation tstringlist [Résolu]

loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 13 juin 2005 à 12:28 - Dernière réponse : florenth
Messages postés
1105
Date d'inscription
dimanche 1 août 2004
Dernière intervention
17 août 2008
- 14 juin 2005 à 15:28
bonjour tout le monde,


J'ai fait une petite fonction qui renvoit un TStringList. Mais je me demande comment je dois m'y prendre pour créer et libérer l'objet TStringList. voici ma fonction:

function BodyMsgDemarrage: TStringList;
begin
Result := TStringList.Create;
Result.Clear;
Result.Add('Le serveur a été démarré avec la configuration suivante');
Result.Add('Port : ' + FPort);
Result.Add('Client TimeOut : ' + FClientTimeout );
Result.Add('Timeout interval : ' + FTimeoutInterval );
end;

Mon problème est donc de savoir où faire le create et faire le free... pour l'instant je fais donc mon create dans la fonction elle-meme. mais je ne fais jamais de free...
je suppose que ce n'est pas bon mais je ne sais pas comment m'y prendre ... pourriez vous me donner votre avis sur la question?
merci d'avance

loic
Afficher la suite 

Votre réponse

15 réponses

Meilleure réponse
ni69
Messages postés
1529
Date d'inscription
samedi 12 juin 2004
Dernière intervention
5 juillet 2010
- 13 juin 2005 à 12:57
3
Merci
Tu ne peux pas libérer result, sinon tu retournes un pointeur ne valant
plus rien de concret... C'est donc l'appelant qui doit le libérer.

Tu ne peux donc pas utiliser de fonction renvoyant une TStringList.
Cependant, tu as la possibilité de faire une procédure, qui, plutôt que
de renvoyer un résultat, modifie une
variable :



var

MaVarTStringList : TStringList; // La variable qui sera utilisée



procedure BodyMsgDemarrage(var TStr : TStringList);

begin

TStr.Clear;

TStr.Add('...');


TStr.Add('...');

end;



procedure MaProc; // Procédure demandant la modification de la variable MaVarTStringList

begin

MaVarTStringList := TStringList.Create; // On crée la variable

Try

BodyMsgDemarrage(MaVarTStringList); // On modifie la variable

{traitement de la variable}

Finally

MaVarTStringList.Free; // On libère la variable

End;

end;







@+
Bonne Prog'
Nico

<hr>

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !




www.ni69.new.fr</italique>

Merci ni69 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de ni69
Meilleure réponse
ni69
Messages postés
1529
Date d'inscription
samedi 12 juin 2004
Dernière intervention
5 juillet 2010
- 13 juin 2005 à 17:33
3
Merci
Tes résultats rejoignent donc ce que j'ai dit dans mon post précédent,
la variable n'est pas vraiment libérée... Je ne vois aucun autre moyen
de procéder que d'utiliser une procédure...



@+
Bonne Prog'
Nico

<hr>

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !




www.ni69.new.fr</italique>


Merci ni69 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de ni69
Meilleure réponse
ni69
Messages postés
1529
Date d'inscription
samedi 12 juin 2004
Dernière intervention
5 juillet 2010
- 14 juin 2005 à 13:24
3
Merci
lol japee , c'est tellement simple qu'on y pense même pas !!!



loicbernard >> une variable TStrings à une propriété 'Text', et c'est là qu'intervient la fonction de japee

par exemple, pour remplir une variable TStrings nommé Lignes avec le
result de la fonction (une variable string), tu peux faire :

Lignes.Text := BodyMsgDemarrage;



@+
Bonne Prog'
Nico

<hr>

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !




www.ni69.new.fr</italique>

Merci ni69 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de ni69
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 13 juin 2005 à 14:02
0
Merci
merci de ta réponse rapide
oui j'ai pensé à cette solution...
maisj'aimerais vraiment que ce soit une fonction qui renvoit le tstringlist pour une facilité d'utilisation et parceque si ca marche ca doit etre plsu joli...
voici ma procedure qui utilise ma fonction tstringlist...

procedure maprocedure();
begin
...
Sendmail('mon titre', BodyMsgDemarrage
)
//BodyMsgDemarrage.free;

...
end

tu dis qu'on ne peut pas utiliser de fonction renvoyant un tstringlist ... je veux bien te croire mais comme elle est écrite ma fonction fonctionne() ... le seul truc c'est que je veux savoir si je dois "libérer ma fonction" après utilisation ou non (ligne en commentaire ... et ca marche aussi quand elle est pas en commentaire)

une autre solution serait ceci mais j'aime pas non plus ... (en fait c'est ma première solution que je trouve la plus pratique(sans le free) mais je crains que la libération ne se fasse pas tout seul)

function BodyMsgDemarrage: TStringList;
begin
Result.Clear;
Result.Add('Le serveur a été démarré avec la configuration suivante');
Result.Add('Port : ' + FPort);
Result.Add('Client TimeOut : ' + FClientTimeout );
Result.Add('Timeout interval : ' + FTimeoutInterval );
end;

procedure maprocedure();
begin
bodymsgdemarrage := tstringlist.create;
Sendmail('mon titre', BodyMsgDemarrage
)
bodymesgdemarrage.free;
end
Commenter la réponse de loicbernard
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 13 juin 2005 à 14:11
0
Merci
voilà j'ai trouvé quelqu'un qui a voulu faire comme moi(cf 2ème message du lien ci dessous)http://www.delphifr.com/forum.v2.aspx?id=271202

est ce la bonne méthode si je veux absolument faire une fonction et non une procedure?
Commenter la réponse de loicbernard
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 13 juin 2005 à 17:24
0
Merci
tiens j'ai l'impression que je suis tout seul sur ce coup là
bon ben voilà j'ai fait quelques tests...

je peux déjà vous dire que

procedure maprocedure();
begin
bodymsgdemarrage := tstringlist.create;
Sendmail('mon titre', BodyMsgDemarrage
)
bodymesgdemarrage.free;
end

ca marche pas... la partie de gauche n'est pas affectable...


et en plus


ma première idée semble TRES mauvaise...avec ou sans le free :

procedure maprocedure();
begin
...
Sendmail('mon titre', BodyMsgDemarrage
)
//BodyMsgDemarrage.free;

...
end

j'ai fait une petite boucle qui apelle 20000 fois la fonction bodydemsgdemarrage et en regardant avce le gestionnaire de tache... je vois que l'occupation mémoire de mon processus explose...(meme avec le free!!!)

d'où je suis revenu à l'idée de départ (celle de ni69)... suis un peu décu qu'on puisse pas faire une fonction qui renvoit un objet mais bon je n'en mourrai pas...
si quelqu'un a néanmoins une bonne idée sur le sujet n'hésiter pas

quoiqu'il soit merci nico
Commenter la réponse de loicbernard
ni69
Messages postés
1529
Date d'inscription
samedi 12 juin 2004
Dernière intervention
5 juillet 2010
- 13 juin 2005 à 17:28
0
Merci
Je te comprends quand tu dis préférer utiliser une fonction, effectivement, ça fait plus propre dans le code



Quand je disais qu'on ne pouvait pas utiliser de fonction renvoyant une
TStringList, c'était que je ne voyais aucun moyen de libérer la
TStringList renvoyée par la fonction... Mais apparement, je me suis
trompé , désolé...



J'ai regardé la méthode de japee, effectivement, elle marche, mais cependant, j'émets un doute : je ne suis pas sûr que la StringList renvoyée par la fonction appelée la première fois [ListBox1.Items.Assign(Transfert(Memo1))] soit libérée, car pour effectuer l'appel de la méthode Free, on appelle une deuxième fois la fonction [Transfert(Memo1).Free;], ce qui crée une deuxième StringList, donc au final, on libère la deuxième StringList, mais pas la première... (du moins c'est ce que je crois...)



Si quelqu'un pouvait nous éclairer sur les différents détails de ce
code et/ou sur la meilleure façon de procéder, j'en serais ravi !



@+
Bonne Prog'
Nico

<hr>

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !




www.ni69.new.fr</italique>
Commenter la réponse de ni69
ni69
Messages postés
1529
Date d'inscription
samedi 12 juin 2004
Dernière intervention
5 juillet 2010
- 13 juin 2005 à 17:30
0
Merci
désolé, j'ai posté en même temps... je regarde ce que tu as écris...



@+
Bonne Prog'
Nico

<hr>

N'oubliez pas de cliquer sur Réponse acceptée lorsque la réponse vous convient !




www.ni69.new.fr</italique>
Commenter la réponse de ni69
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 13 juin 2005 à 17:36
0
Merci
me voilà bien triste...
en tout cas merci beaucoup

si jamais quelqu'un avait une autre solution n'hésitez pas
Commenter la réponse de loicbernard
florenth
Messages postés
1105
Date d'inscription
dimanche 1 août 2004
Dernière intervention
17 août 2008
- 13 juin 2005 à 17:46
0
Merci
Oui ni69, la réponse que m'a donné Japee est fausse: comme tu le dis,
la fonction est rapellée une deuxième fois et c'est cette deuxième
instance qui est libérée, pas la 1ere ...



Il faut donc passer par un parametre dans une procéduree ou une fonction de la sorte:

function MaFunc: TStringList;

begin

Result: =TStringList.Create;

Result.Add('Ma chaine');

end;

que l'on appelle ainsi:

procedure MaProc;

var

Sl: TStringList;

begin

Sl: =MaFunc;

Sl.Free;

end;



@ ++

Florent



Si tu ne te plantes pas ......
tu ne poussera jamais
Commenter la réponse de florenth
japee
Messages postés
1799
Date d'inscription
vendredi 27 décembre 2002
Dernière intervention
19 juillet 2018
- 13 juin 2005 à 22:52
0
Merci
Ouais, Florenth, je crois que je m'étais un peu planté sur ce coup là...



Arrêtez-moi si je dis une bêtise, mais pourquoi ne pas utiliser une fonction qui retournerait un String ?



function BodyMsgDemarrage: String;

begin

Result := 'Le serveur a été démarré avec la configuration suivante' + #13 +

'Port : ' + FPort + #13 +

'Client TimeOut : ' + FClientTimeout + #13 +

'Timeout interval : ' + FTimeoutInterval;

end;




Ainsi, pas besoin de créer, ni de libérer quoi que ce soit.

Et on a une fonction qui retourne un résultat bien propre...



Bonne prog'



japee
Commenter la réponse de japee
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 14 juin 2005 à 12:48
0
Merci
merci du dévouement de chacun...
florent :
oui mais mon problème c'est ma fonction sendmail(mybodymessage) remplit la propriété body(c'est un TStrings) du composants IdMessage(composant indy) ...et je ne vois pas comment appliquer ta solution dans ce cas là...


japee:
le problème est que comme je l'expliquais ci dessus au final je dois remplir un TStrings...
Commenter la réponse de loicbernard
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 14 juin 2005 à 12:49
0
Merci
zut la fin du message a encore été coupée...

je disais juste : quoiqu'il en soit merci à tous

lolo
Commenter la réponse de loicbernard
loicbernard
Messages postés
17
Date d'inscription
jeudi 22 mai 2003
Dernière intervention
15 juin 2005
- 14 juin 2005 à 13:41
0
Merci
magnifique... ben voilà c'est (presque )ca que je voulais ;-)

je vous remercie (oui je sais que je l'ai déjà 5 fois mais j'insiste ) de votre aide...

lolo
Commenter la réponse de loicbernard
florenth
Messages postés
1105
Date d'inscription
dimanche 1 août 2004
Dernière intervention
17 août 2008
- 14 juin 2005 à 15:28
0
Merci
Loïc > C'était uste un exemple pour te montrer que c'est possible.

Nico > A ce compte là, ma fonction convient aussi (de même qu'une
procedure avec param variable) puisqu'il faut quand même déclarer une
variable pour s'en servir. Et en plus, il faut que l'appelant la crée
et la libère ...



Japee > Mais pourquoi pas ? On s'embette vraiment pour rien ...

Mais il faut savoir que, même si c'est transparant, que Delphi, lui, alloue et libère la memoire associée à un type string.



C'est pas grave si tu t'es trompé en me répondant sur l'autre message. Parce que
Si tu ne te plantes pas ......
tu ne poussera jamais (eh oui)



Et voila !!



@ ++

Florent
Commenter la réponse de florenth

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.