通常函数要返回 TStrings 的话,都是以 var a: TStrings 的形式返回,如:
function f(var a: TStrings): Boolean;
调用前,先 Create 一下。请问下面的写法有没有什么问题?函数调用完后 Result 对应内存就被释放了吗?不甚明白,请大虾们指点!
procedure TForm1.Button1Click(Sender: TObject);
  function a(): TStrings;
  begin
    Result := TStringList.Create();
    Result.Add('a');
  end;
begin
  ShowMessage(a()[0]);
end;

解决方案 »

  1.   

    这样是不会自动释放的, 因为delphi中的对象没有自动生命周期管理, 除了像接口, string, 动态数组这几种类型是带有引用计数控制的, 所以你创建的StringList必须要你自己释放掉
    一般情况下使用下面的方式操作StringList
    a: = TStringList.Create;
    try
      Test(a);
      ..... //这里可以操作a对象.
    finally
      a.free;
    end;其中Test函数可以是这样的
    procedure Test(const strlist: TStringList);
    begin
      strList.add('a');
    end;
      

  2.   

    真的吗?
    那这样该释放了吧?
    procedure TForm1.Button1Click(Sender: TObject);
      function a(): TStrings;
      begin
        Result := TStringList.Create();
        Result.Add('a');
      end;
    begin
      with a() do
      begin
        ShowMessage(Strings[0]);
        Free;
      end;
    end;
      

  3.   

    这样是释放了, 但是尽量少用With, 以后你写的层数多了, 就知道With容易搅浑思维. 尤其是对象有同名的参数或者是方法时, 但是我不是说不用With, 看场合
      

  4.   

    lz搞清楚在函数里面分配内存有2种情况,一种是分配地栈内存---这种情况在函数退出的时候就已经释放了。这里主要是delphi中简单数据类型。
    然而还有一种情况就是分配的堆内存,这种情况在函数退出的时候是不会释放的,需要自己来释放(我这里讲的函数和过程是指你自己定义的,vcl中除外)。也就是说你退出函数的时候申请的那块东西照样存在。这里主要包括new() 对象(create)。
      

  5.   

    procedure TForm1.Button1Click(Sender: TObject);
      function a(): TStrings;
      begin
        Result := TStringList.Create();
        Result.Add('a');
      end;
    begin
      ShowMessage(a()[0]);
    end;
    对于上面一段代码,在执行函数a()之后还没有立即释放,然后执行完Button1的click事件后应当释放了吧?
      

  6.   

    没有释放,堆上分配的内存 要手动释放(delphi 生存期自管理类型除外...),
    要执行free后才会释放地。
      

  7.   

    lz 可以多写几个例子test下。
      

  8.   

    分配在堆中的内存,是不会自动释放的(用接口机制另当别论)
    退出click后,释放的仅仅是在栈上的StringList的引用
      

  9.   

    这么说吧, 对于TStringList这样的对象你没有写Free 是不会释放的, 不管你的线程是否结束, 过程是否结束, 这样说理解了吗, 就是说必须要你手工释放, 如果你对自动生命周期管理感兴趣 可以看以下, delphi2010 中实现的smartpointer例子, 这个在marcoo的博客里有的, 利用了新的语言特性.