Der Aufruf von Free gibt lediglich den Speicher, den das Objekt belegt frei - das bedeutet, dass der vorher belegte Speicherbereich nun als erneut verwendbar markiert wird. Da Delphi eine eigene Speicherverwaltung besitzt wird dies u.U. nicht einmal dem Betriebsystem mitgeteilt: Der Objektzeiger "o" wird nicht verändert und die Daten des Objekts liegen immer noch im Speicher. Da du zwischen dem Free und dem Writeln keinen neuen Speicher reservierst, werden deine alten Objektdaten auch nicht überschrieben.
Sobald du neuen Speicher reservierst (dies kann auch durch Bibliotheksaufrufe, verändern der Größe eines Arrays etc.) besteht jedoch die Wahrscheinlichkeit, dass der Speicher des Objektes überschrieben wird und du mit jedem lesenden Zugriff auf das Objekt Müll ausliest und mit jedem schreibenden Zugriff beliebige andere Daten zerhackst, was zu sehr interessanten Fehlern führen kann.
Deshalb: Objekte frei geben und dann immer alle Objektzeiger darauf auf "nil" setzen. Versuchst du dann auf das Objekt zuzugreifen bekommst du eine aussagekräftige Fehlermeldung ("EAccessViolation while reading address 0x00000000"):
oder einfacher:
FreeAndNil(o);
Edit:
Im Falle von Methoden (wie in deinem Beispiel) ist die Sache noch ein wenig komplizierter. Intern sind alle (nicht virtuellen) Methoden einfache Funktionen, die einen versteckten, ersten Parameter "self" beinhalten, der den Wert des Objektzeigers hat. Folgendes ist also equivalent zu deinem Code:
Delphi-Quellcode:
type
TblObject = record
name: string;
end;
PblObject = ^TblObject;
function blObject_Create: PblObject;
begin
new(result);
end;
procedure blObject_SetName(self: Pointer; name: string);
begin
self^.name := name;
end;
function blObject_GetName(self: Pointer): string;
begin
result := self^.name;
end;
procedure blObject_Free(self: Pointer);
begin
Dispose(self);
end;
var
o: PblObject;
begin
o := blObject_Create();
blObject_setName(o, 'name');
blObject_free(o);
writeln(blObject_getName(o));
end;
Die Methoden sind wie du siehst fest im Programmcode enthalten und sind nach Freigabe eines Objektes immer noch gültig. Solange eine nicht virtuelle Methode nicht auf Objektvariablen zugreift (also den versteckten "self" Parameter nicht verwendet), wird die Funktion immer ohne Fehlermeldung ausgeführt, selbst wenn "self" nil sein sollte. In deinem Fall trifft jedoch einfach das oben gesagte zu, nämlich dass die Freigabe den Speicher nur als "zur Wiederverwertung freigegeben" kennzeichnet, den Speicherinhalt jedoch nicht löscht.