Локальная переменная TStringList не инициализирована в ноль - почему?
Я использую этот код, чтобы проверить, TStringList
создан или нет:
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
if not Assigned(sVariable) then
sVariable:= TStringList.Create;
end;
Но условие False
всегда, почему это происходит? Как я могу проверить, если TStringList
объект создан или нет?
Ps Я знаю о подобном вопросе, который я задавал, я попробовал решение, отправленное в том, но оно не работает для меня.
5 ответов
Вы можете предположить, что объект не создан и переменная инициализирована мусором (потому что это локальная переменная). Просто создайте свой StringList и все в порядке.
Когда вы выделяете ссылку на объект в стеке, она заполняется случайными значениями (т. Е. Предыдущими значениями в стеке - которые в некоторых случаях могут быть равны нулю). Это по замыслу.
Чтобы проверить, инициализирована ли переменная, вам нужно сначала установить ее вручную nil
, Это очень быстрое задание.
Типичный шаблон кода может быть:
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;
Обратите внимание, что в приведенном выше коде я включил (обязательно ИМХО) try...finally
блок для освобождения памяти. Если sVariable
не было выделено, это все еще nil
и в этом случае sVariable.Free
ничего не сделаю. Это обычная практика в Delphi.
Прежде всего: код, который вы опубликовали, не имеет смысла. Поскольку sVariable является локальной переменной, она всегда неинициализирована. Но в отличие от переменных в объектной области, неинициализированный не означает, что он равен нулю. Delphi не будет устанавливать локальные переменные в ноль. Таким образом, sVariable содержит полностью случайное значение. Функция Assigned() только проверяет, имеет ли значение значение nil, но не указывает, что оно указывает на действительный экземпляр объекта.
Вы можете сделать это напрямую, потому что это локальная переменная
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
sVariable:= TStringList.Create;
end;
После вашего обновления вопрос, что я вижу, кажется вполне нормальным.
Когда вы определяете переменную объекта (sVariable), она не инициализируется, что вы должны сделать с помощью конструктора Create. В этом случае вам даже не нужно проверять, существует ли он или нет.
procedure TForm1.Button1Click(Sender: TObject);
var
sVariable : TStringList;
begin
sVariable:= TStringList.Create;
//Work with the stringlist e.g add items:
sVariable.Add('Blah');
//Make sure it finally gets freed
sVariable.Free;
end;