2010-11-26 39 views
7

Une question très simple:Est-ce que je crée une fuite de mémoire ici?

type 

TMyRecord = Record 
    Int: Integer; 
    Str: String; 
end; 

PMyRecord = ^TMyRecord; 

var 
    Data: PMyRecord; 
begin 
    New(Data); 
    Data.Int := 42; 
    Data.Str := 'Test'; 
    Dispose(Data); 
end; 

Ma question est, je suis crée une fuite de mémoire ici (avec la chaîne)? Dois-je appeler Data.Str: = ''; avant d'appeler Dispose?

Merci!

+0

Je ne pense pas. –

Répondre

12

Non, Dispose libère correctement les chaînes et les tableaux dynamiques dans les enregistrements, y compris ceux imbriqués. GetMem/FreeMem (Data) créerait un poireau de mémoire, en effet.

+3

Ajouter des variantes, des interfaces comptées de référence et peut-être même des fonctions anonymes à la liste, je pense que tout ce qui est référencé est publié sur 'Dispose()'. – Trinidad

+2

GetMem/FreeMem nécessiterait d'appeler Finalize(). Vérifiez Finaliser dans l'aide pour une explication sur ce qu'il fait lorsque Dispose() ne peut pas être utilisé. –

+3

@ldsanson: Nouveau = GetMem + Initialiser et Disposer = Finaliser + FreeMem - vérifier System.pas. Ce ne sont que des wrappers aux deux fonctions. –

0

Non, String nettoie sa propre mémoire lorsqu'elle est supprimée.

+2

En fait: les chaînes se libèrent lorsque la structure englobante est finalisée. –

0

Si vous voulez une fuite de mémoire, autant que je sache, vous devez utiliser des objets TP :-) Ils sont afaik les seuls types structurés de Delphi qui ne sont pas initialisés/finalisés

+2

Les objets TP sont initialisés. Ils sont traités de la même manière que les enregistrements. Nous les avons largement utilisés jusqu'à ce que Delphi ajoute le support pour les enregistrements avec des méthodes. –

+0

L'enregistrement ou l'objet ne crée pas de fuite de mémoire si vous les utilisez en utilisant des tableaux dynamiques ou sur la pile, ce qui est très courant. Seulement avec l'allocation de tas est nécessaire New() et Dispose(). Il n'est pas très difficile d'utiliser New (aRecordPointer) par rapport à unObject.Create ... –

+0

http://groups.google.com/group/comp.lang.pascal.delphi.misc/msg/2176ea3300f2dfb9 Admis, ça vaut pour les objets TP qui ont un VMT. Donc l'utilisation comme enregistrement est correcte, utilisation comme objet non –

10

Il est une fuite de mémoire si une exception est soulevée dans entre vos paires allocate/deallocate. Il est normal de les protéger en tant que tels:

New(Data); 
Try 
    Data.Int := 42; 
    Data.Str := 'Test'; 
Finally 
    Dispose(Data); 
End; 
+1

+1 pour essayer ... enfin –

+0

Vous devriez mieux allouer vos enregistrements soit dans la pile, soit dans un tableau dynamique. Les deux vont initialiser le contenu de chaque article d'enregistrement. Le try..finally est obligatoire pour l'allocation de tas, comme un TObject.Create a besoin d'un try..finally Free. Un tel essai ... sera finalement créé automatiquement par le compilateur si votre enregistrement est alloué via un tableau dynamique ou sur la pile. –

+0

@ArnaudBouchez Allouer dans un tableau si vous voulez un tableau. Pas approprié si vous voulez un seul enregistrement. Allouer sur le tas avec 'New' plutôt que la pile si la durée de vie de l'enregistrement doit survivre à la portée qui crée l'enregistrement. –