TList et désallocation mémoire [Résolu]

Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
- 15 juin 2006 à 22:28 - Dernière réponse :
Messages postés
199
Date d'inscription
dimanche 2 mars 2003
Dernière intervention
10 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.

Thierry
Afficher la suite 

Votre réponse

7 réponses

Meilleure réponse
Messages postés
1651
Date d'inscription
samedi 10 juillet 2004
Dernière intervention
25 juillet 2014
- 15 juin 2006 à 23:00
3
Merci
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)


@+

jlen

Merci jlen100 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de jlen100
Meilleure réponse
Messages postés
199
Date d'inscription
dimanche 2 mars 2003
Dernière intervention
10 octobre 2006
- 16 juin 2006 à 10:57
3
Merci
1 Ne vide que la liste mais pas ce qui est pointé par les éléments de la dite liste.


moi je ferais ca :
4)
with Liste do
begin
  for i:=Count-1 DownTo 0 Do
    If Items[i]<>Nil Then Dispose(pTypePointeur(Items[i]));
  Clear;
end;


Tout problème a sa solution... Mais en général, celle que l'on trouve n'est jamais la bonne...

Merci Emandhal 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de Emandhal
Messages postés
424
Date d'inscription
mardi 3 janvier 2006
Dernière intervention
26 novembre 2013
- 16 juin 2006 à 18:30
0
Merci
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...
Commenter la réponse de ThWilliam
Messages postés
459
Date d'inscription
lundi 19 avril 2004
Dernière intervention
8 avril 2009
- 16 juin 2006 à 23:08
0
Merci
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 ?
Commenter la réponse de DeltaFX
Messages postés
1651
Date d'inscription
samedi 10 juillet 2004
Dernière intervention
25 juillet 2014
- 16 juin 2006 à 23:24
0
Merci
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


@+

jlen
Commenter la réponse de jlen100
Messages postés
459
Date d'inscription
lundi 19 avril 2004
Dernière intervention
8 avril 2009
- 17 juin 2006 à 10:27
0
Merci
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.

C'est au choix.
Commenter la réponse de DeltaFX
Messages postés
199
Date d'inscription
dimanche 2 mars 2003
Dernière intervention
10 octobre 2006
- 17 juin 2006 à 11:40
0
Merci
La plupart du temps je refais ma propre liste, pour des Record, en partant de TObject et j'y met juste cedont j'ai besoin.


Tout problème a sa solution... Mais en général, celle que l'on trouve n'est jamais la bonne...
Commenter la réponse de Emandhal

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.