Локальная переменная 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; 
Другие вопросы по тегам