When you allocate an object reference on the stack, it is filled with random values (i.e. the previous values on the stack - which may be nil in some border cases). This is by design.
In order to check if the variable is initialized, you'll have first to set it manually to nil. This is a very fast assignment.
A typical code pattern may be:
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
sVariable := nil; // initialize explicitely
try
(...) // in this hidden part sVariable may be instantiated
if not Assigned(sVariable) then // instantiate if not already done
sVariable:= TStringList.Create;
(...)
finally
sVariable.Free; // will do nothing if sVariable=nil
end;
end;
Note that in the above code, I've included a (mandatory IMHO) try...finally block to release the memory. If sVariable was not allocated, it is still nil, and in this case sVariable.Free will do nothing. It is an usual best practice pattern in Delphi.