Faut-il vraiment utiliser FreeAndNil() dans nos programmes en Pascal ?

Il y a parfois débat sur la pertinence d'utiliser ou pas la commande FreeAndNil() de l'unité System.SysUtils pour libérer des instances de classes.

Autant pour l'instruction "with" je n'ai aucun doute sur le fait que ce soit un non presque ferme et définitif (pour la lisibilité et la maintenance du code), autant pour FreeAndNil() je suis partagé et m'en sers ponctuellement.

J'alloue, je libère

D'une façon générale, quand on réserve une zone mémoire il faut penser à la libérer ou faire en sorte qu'elle se libère d'elle-même. Si on ne le fait pas on se retrouve avec des pertes mémoires en utilisation de nos logiciels. Bien entendu c'est réglé à la fermeture mais si vos programmes tournent longtemps ça peut avoir des effets de bord.

Les composants possèdent un système de gestion mémoire intégré qui permet leur libération par leur propriétaire (s'ils en ont un).

Pour les instances de classes, en revanche, c'est à nous de faire le nécessaire sauf dans des cas particuliers (par exemple la librairie System.JSON).

Si on utilise un constructeur sur une classe, on doit appeler la méthode Free quand on ne s'en sert plus.

Le fait d'affecter "nil" à une variable ne libère pas la mémoire associée. Ca se contente d'initialiser la variable qui pointait sur la zone mémoire. Donc non seulement on perd la mémoire mais aussi la seule façon d'y accéder.

Pourquoi utiliser FreeAndNil() ?

La procédure FreeAndNil() permet d'appeler la méthode Free d'une instance de classe avant de réinitialiser le pointeur en lui affectant la valeur "nil".

Ca n'a d'intérêt que lorsqu'on se sert de la variable ailleurs et qu'on gère le fait qu'elle soit affectée ou pas à une instance de classe.

Donc soyons clairs, FreeAndNil() ne doit pas être d'un usage courant dans un programme sauf si vous utilisez des variables globales dans le programme, dans une implémentation d'unité ou sous forme de champ d'une classe.

Si vous n'utilisez pas Assigned() ou ne testez pas vos variables par rapport à "nil" avant de vous en servir, vous n'avez pas besoin de FreeAndNil() (ou vous avez une source de violations d'accès).

S'il vous arrive de ne pas initialiser toutes les variables de type classe dans un programme et que vous vous en servez de temps en temps, dans ce cas vous avez le droit de passer par FreeAndNil() parce que vous allez forcément avoir un "if variable<>nil" ou "if assigned(variable)" dans votre code pour les instancier et qu'il faut donc les mettre à "nil" quand vous libérez l'instance.

Ceci dit, si vous n'avez besoin de rien d'autre dans System.SysUtils, vous pouvez vous contenter d'appeler Free et mettre votre variable à "nil" à la main, pas besoin de faire un Uses juste pour ça.