ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 2013
-
15 juin 2006 à 22:28
Emandhal
Messages postés194Date d'inscriptiondimanche 2 mars 2003StatutMembreDernière intervention10 octobre 2006
-
17 juin 2006 à 11:40
Bonjour à tous.
Ma question porte sur la désallocation mémoire des éléments d'un TList.
Pour ajouter des éléments, méthode classique :
New(MonPointeur);
MonPointeur^ := Value;
Liste.Add(MonPointeur);
Pour libérer tous les éléments, là je trouve 3 méthodes :
1) Liste.Clear : j'ai jeté un coup d'oeil dans l'unité Classes :
Clear fait :
for i:= FCount-1 downto 0 do Delete(i);
Delete ne fait dans ce cas que décrémenter FCount, puis fait un appel à Notify, cette procedure ne faisant rien puisque déclarée virtual.
Enfin Clear met Capacity à zéro ce qui provoque :
ReallocMem(FList, NewCapacity * Sizeof(Pointer)) --> c.àd. zéro
2) code trouvé sur ce site (de nono40 je pense) :
with Liste do
for i:=Count-1 DownTo 0 Do
begin
If Items[i]<>Nil Then Dispose(Items[i]);
Liste.Delete(i);
end;
3) code dans les exemples de l'aide Delphi :
for i := 0 to (Liste.Count - 1) do
begin
MonPoiteur := Liste.Items[i];
Dispose(MonPointeur);
end;
Clear , d'après moi, ne désalloue pas les éléments de la liste (sauf si on surchargeait Notify).
Je penche donc pour 2) ou 3)
Test avec 2.000.000 d'éléments :
1) quasi instantané
2) un peu plus long
3) beaucoup plus long
Je serais intéressé de connaitre votre avis.
Merci d'avance.
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 15 juin 2006 à 23:00
salut,
dans le cas 1 on ne fait que libérer l'espace mémoire correspondant à l'objet pas pas celui des données.
dans le cas 2 il peut y avoir un problème de perte mémoire en effet
quand on libère directement au niveau du pointeur de liste (pointeur
non typé) il n'est pas sur que le programme reconnaisse le type de
strcuture associée (cas d'un reccord) alors que le fait de transferer
le pointeur sur une vraible typée asure que l'on libère bien l'espace
correspondant à cette structure donc si la strcture est complexe il ne
dvrait y avoir que pour d'écart de temps de traitement entre les 2
(affectation de la varaible corespondant à une copie de 4 octets par
variable : copie de bloc qui si j'ai bonne mémoire doit représenter une
dizaine de cycle machine par octet soit ~40 cycles soit 80 000 000 pour
ton cas autant dire rien à 2 ou 3 GHz)
ThWilliam
Messages postés418Date d'inscriptionmardi 3 janvier 2006StatutMembreDernière intervention26 novembre 20134 16 juin 2006 à 18:30
Salut jlen et Emandhal,
Grand merci à vous deux.
Nous sommes tous d'accord au sujet de Clear : il ne libère pas les éléments pointés. Et Free ne fait qu'appeler Clear.
J'ai fait un petit test avec pointeur sur une variable de type record.
J'ajoute 2.000.000 d'éléments dans la liste.
Avec un petit programme qui me montre l'occupation mémoire vive, je vois que cela prend 250 Mo.
La méthode Clear : ne permet de récupérer qu'environ 8 mégas (je crois qu'un pointeur est codé sur 4 octets, cela correspondrait donc à l'espace mémoire des pointeurs).
La méthode 2) : ne fait rien de mieux (en tout cas avec un pointeur sur record).
La méthode 3) : à condition de lui rajouter un Clear, je récupère l'entièreté des 250 mégas.
La méthode de Emandhal est parfaite : on libère l'espace mémoire des données, puis celui des pointeurs. Je l'adopte !
A +
Thierry
PS: Emandhal, tu vas devoir réviser ton proverbe...
DeltaFX
Messages postés449Date d'inscriptionlundi 19 avril 2004StatutMembreDernière intervention 8 avril 20092 16 juin 2006 à 23:08
M'enfin si c'est pour stocker des pointeurs vers des objets, y a TobjectList qui par defaut OwnObject (a moins qu'on lui spécifie que non au create) et quand on le vide, il libère tout bien.
Ou alors me goure-je ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
jlen100
Messages postés1606Date d'inscriptionsamedi 10 juillet 2004StatutMembreDernière intervention25 juillet 201413 16 juin 2006 à 23:24
salut deltaFX d'accord avec toi si tu ne travailles qu'avec des objets
mais dans ce qui est dit précédément pour les TList on ne stocke pas
que des objets (par exemple si tu charges un fichier les
enregistrements ne sont pas des objets) et dans ce cas tu ne peux pas
utliser le TObjectList il faut donc gérer la libération de la mémoire
DeltaFX
Messages postés449Date d'inscriptionlundi 19 avril 2004StatutMembreDernière intervention 8 avril 20092 17 juin 2006 à 10:27
Je disais ca, Tlist c'est l'ancetre commun, mais il a une floppé de dérivés. Avant de taper dans Tlist, il y a peut-etre des structures toutes pretes, qui ont déja toutes les functions voulues.
Accessoirement, y a 2 approches, soit on repart de Tlist, on le dérive, on rajoute ce qu'on veut pour qu'il colle pil poil aux données qu'on manipule, soit on part d'un dérivé (dans mon cas TObjectList) et on réemballe ses données pour qu'elles collent à la structure.