对象的生命周期

s11ss 2010-01-20 06:37:29
通常函数要返回 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;
...全文
108 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Hexpate 2010-01-21
  • 打赏
  • 举报
回复
这么说吧, 对于TStringList这样的对象你没有写Free 是不会释放的, 不管你的线程是否结束, 过程是否结束, 这样说理解了吗, 就是说必须要你手工释放, 如果你对自动生命周期管理感兴趣 可以看以下, delphi2010 中实现的smartpointer例子, 这个在marcoo的博客里有的, 利用了新的语言特性.
kfcoffe 2010-01-21
  • 打赏
  • 举报
回复
要你手动释放才释放啊,除非主程序退出,不然一直在那。
s11ss 2010-01-21
  • 打赏
  • 举报
回复
看来线程退出后才释放?[Quote=引用 8 楼 liangpei2008 的回复:]
分配在堆中的内存,是不会自动释放的(用接口机制另当别论)
退出click后,释放的仅仅是在栈上的StringList的引用
[/Quote]
liangpei2008 2010-01-20
  • 打赏
  • 举报
回复
分配在堆中的内存,是不会自动释放的(用接口机制另当别论)
退出click后,释放的仅仅是在栈上的StringList的引用
kfcoffe 2010-01-20
  • 打赏
  • 举报
回复
lz 可以多写几个例子test下。
kfcoffe 2010-01-20
  • 打赏
  • 举报
回复
没有释放,堆上分配的内存 要手动释放(delphi 生存期自管理类型除外...),
要执行free后才会释放地。
s11ss 2010-01-20
  • 打赏
  • 举报
回复
procedure TForm1.Button1Click(Sender: TObject);
function a(): TStrings;
begin
Result := TStringList.Create();
Result.Add('a');
end;
begin
ShowMessage(a()[0]);
end;

对于上面一段代码,在执行函数a()之后还没有立即释放,然后执行完Button1的click事件后应当释放了吧?[Quote=引用 4 楼 kfcoffe 的回复:]
lz搞清楚在函数里面分配内存有2种情况,一种是分配地栈内存---这种情况在函数退出的时候就已经释放了。这里主要是delphi中简单数据类型。
然而还有一种情况就是分配的堆内存,这种情况在函数退出的时候是不会释放的,需要自己来释放(我这里讲的函数和过程是指你自己定义的,vcl中除外)。也就是说你退出函数的时候申请的那块东西照样存在。这里主要包括new() 对象(create)。。。。

[/Quote]
kfcoffe 2010-01-20
  • 打赏
  • 举报
回复
lz搞清楚在函数里面分配内存有2种情况,一种是分配地栈内存---这种情况在函数退出的时候就已经释放了。这里主要是delphi中简单数据类型。
然而还有一种情况就是分配的堆内存,这种情况在函数退出的时候是不会释放的,需要自己来释放(我这里讲的函数和过程是指你自己定义的,vcl中除外)。也就是说你退出函数的时候申请的那块东西照样存在。这里主要包括new() 对象(create)。。。。
Hexpate 2010-01-20
  • 打赏
  • 举报
回复
这样是释放了, 但是尽量少用With, 以后你写的层数多了, 就知道With容易搅浑思维. 尤其是对象有同名的参数或者是方法时, 但是我不是说不用With, 看场合
s11ss 2010-01-20
  • 打赏
  • 举报
回复
真的吗?
那这样该释放了吧?
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;


[Quote=引用 1 楼 hexpate 的回复:]
这样是不会自动释放的, 因为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;
[/Quote]
Hexpate 2010-01-20
  • 打赏
  • 举报
回复
这样是不会自动释放的, 因为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;

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧