Un objet non libéré ne provoque pas d'erreur ... du moins il ne le doit pas.
tant qu'une instance est valide il ne peut pas y'avoir de violation d'accés a cette derniere.
par contre, une instance non allouée ou deja libérée devient irremediablement invalide et donc un appel a une telle instance provoque immediatement une violation d'accés car l'addresse memoire ne pointe plus sur un espace memoire valide.
c'est pour cela qu'il existe des fonctions tel Assigned ou FreeAndNil ou même la valeur Nil (Null).
une reference (objet ou pointeur) doit toujours etre remis a Nil pendant l'execution d'un programme, car tant que ce n'est pas fait l'instance contient toujours une addresse memoire.
cette reference n'est rien d'autre qu'une variable qui stocke une addresse memoire sur un entier 32bit, cette addresse memoire nous permet d'acceder a un espace memoire qui vas contenir les données soit d'un objet, soit d'un type quand il s'agit d'un pointeur.
il une erreur frequente, qui aboutie sur une violation d'accés :
- l'appel d'un constructeur de classe sans assignation de son retour (appel direct de Create sans assignation) :
"MonObjet.Create" au lieu de "MonObjet := ClasseObjet.Create" ou "With ClasseObjet.Create do"
qu'est-ce qui se passe dans ce cas :
MonObjet.Create; { on crée une reference mais elle est immediatement perdue }
MonObjet.Caption := 'oops'; { violation d'accés, MonObjet n'est pas une reference valide }
MonObjet.Free; { violation d'accés, MonObjet n'est pas une reference valide }
par contre :
MonObjet := ClasseObjet.Create; { on crée une reference est elle est assignée a MonObjet }
MonObjet.Caption := 'ouf!'; { pas de probleme }
MonObjet.Free; { pas de probleme ici non plus }
MonObjet.Caption := 'i''m an idiot!'; { violation d'accés sur tentative d'accés a une instance detruite }
With ... Do fonctionne comme si on utilisait la variable MonObjet donc :
with ClasseObjet.Create do { pas de probleme }
try
Caption := 'youpi!'; { pas de probleme }
finally { assure la certitude de la liberation }
Free; { pas de probleme }
Caption := 'Idée stupide'; { violation d'accés sur tentative d'accés a une instance detruite }
end;
remettre a Nil une reference permet d'effectuer un test simple avant un code, ce test permet de reduire les violation d'accés, mais on devrat toujours etre vigilant a ce que l'on fait.
on peut donc faire :
if not Assigned(MonObjet) then { assure qu'on ne vas pas ecrasser une instance existante }
MonObjet := ClasseObjet.Create;
try
{ exploitation de MonObjet }
finally
FreeAndNil(MonObjet); { libere et remet a nil la reference pour assigned() }
end;
voila pour les objets, le concept est le même pour les pointeurs, car une reference d'objet n'est rien d'autre qu'un pointeur, a peu de choses prés.