TStringList局部变量未初始化为nil - 为什么?

时间:2011-11-04 10:23:08

标签: delphi delphi-7 tstringlist

我正在使用此代码检查是否创建了TStringList

procedure TForm1.Button1Click(Sender: TObject);
var

  sVariable : TStringList;
begin
   if not Assigned(sVariable) then
   sVariable:= TStringList.Create;
end; 

但条件总是False,为什么会这样?如何检查是否创建了TStringList对象?

P.S。我知道有一个类似的问题问题,我尝试了在那个问题上发布的解决方案,但它对我不起作用。

5 个答案:

答案 0 :(得分:15)

当您在堆栈上分配对象引用时,它会填充随机值(即堆栈上的先前值 - 在某些边界情况下可能为零)。这是设计的。

为了检查变量是否已初始化,您首先要手动将其设置为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; 

请注意,在上面的代码中,我已经包含一个(强制IMHO)try...finally块来释放内存。如果未分配sVariable,则它仍为nil,在这种情况下,sVariable.Free将不执行任何操作。这是Delphi中常见的最佳实践模式。

答案 1 :(得分:8)

您可以假设未创建对象和变量initialized with garbage(因为它是局部变量)。只需创建你的StringList,一切都很好。

答案 2 :(得分:7)

首先:你发布的代码毫无意义。因为sVariable是局部变量,所以它总是未初始化的。 但与对象范围中的变量不同,未初始化并不意味着它是零。 Delphi不会将局部变量设置为nil。所以sVariable包含一个完全随机的值。 Assigned()仅检查值是否为nil - 而不是它是否指向对象的有效实例。

答案 3 :(得分:3)

你可以直接这样做,因为它是一个局部变量

procedure TForm1.Button1Click(Sender: TObject);
var
  sVariable : TStringList;
begin
  sVariable:= TStringList.Create;
end;

答案 4 :(得分:3)

更新问题后,我看到的情况似乎很正常。

当你定义一个对象变量(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;