关于对象与对象的释放的困惑

xyqxj 2004-07-08 04:01:11
我在使用列表类型的时候,为了便于下一步的数据操作,使用了addobject方法,该方法需要一个对象的指针,于是我建立了一个TobjectList的全局对象Alist,并且使用自定义的类声明了一个局部对象AData,在循环里面给局部对象AData赋值。当我需要加到列表时,发现AData不能释放,否则出现取地址错误!他会自动释放吗?,另外要使用列表的Addobject方法,使用addobject(Pointer(Ainteger))与Addobject(Alist.items)哪个好些呢?Addobject(Alist.items)是不是占用了更多的内存?
望指教!
...全文
215 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
IFindit 2004-07-11
  • 打赏
  • 举报
回复
结?
xyqxj 2004-07-09
  • 打赏
  • 举报
回复
明白了,晚上结贴!!谢谢大家了!
killghost 2004-07-09
  • 打赏
  • 举报
回复
看看TObjectList你可以知道没有Create(nil);这种说法。

我上面已经说过了。在你如果你创建FList时,采用的是:FList:=TObjectList.Create(True); 那么你后面循环创建的对象AData,就不需要释放。在FList.free;时系统帮你释放。下面是系统释放释放时候的处理。
procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
if OwnsObjects then
if Action = lnDeleted then
TObject(Ptr).Free;
inherited Notify(Ptr, Action);
end;
xyqxj 2004-07-09
  • 打赏
  • 举报
回复
我用的是create(nil)
我说的不是TobjectList的释放问题,而是为了添加而创建的pointer或者Object的释放问题,为了添加到TobjectList,是不是要循环的分配地址或者创建对象实例?如果是怎么释放?
killghost 2004-07-09
  • 打赏
  • 举报
回复
TObjectList.Create的说明
方法一:TobjectList.Create;
Delphi中的定义:
constructor TObjectList.Create;
begin
inherited Create;
FOwnsObjects := True;
end;
方法二:TobjectList.Create(AOwnsObjects: Boolean);
constructor TObjectList.Create(AOwnsObjects: Boolean);
begin
inherited Create;
FOwnsObjects := AOwnsObjects;
end;
也就是说:在创建FList的时候,你可以指定其时候拥有对象,如果AOwnsObjects=True;那么,Delphi就帮你释放对象,这时你创建的对象AData就不需要释放。
Delphi在释放时候的代码:

procedure TObjectList.Notify(Ptr: Pointer; Action: TListNotification);
begin
if OwnsObjects then
if Action = lnDeleted then
TObject(Ptr).Free;
inherited Notify(Ptr, Action);
end;
所以说如果你是采用的FList:=TObjectList.Create(True);这种方式来创建的对象的话你就不用释放Adata;

注:FList:=TObjectList.Create(True); 等价于 FList:=TObjectList.Create;
JavaD 2004-07-09
  • 打赏
  • 举报
回复
你new了,之后放在list的的Object数组里,随时取用啊,在你不用的时候,从数组里取出来dispose啊,感觉你仿佛混淆了流程呢?
var
a:PMyRecord;
begin
new(a);
只是为了生成你的变量,不能释放a,也不用担心内存泄漏,因为这块内存已经有Objects[i]这个指针来指向了,需要释放的时候把它强制转化成PMyRecord,再dispose,就没有问题了
xyqxj 2004-07-09
  • 打赏
  • 举报
回复
我用的是TobjectList的全局对象Alist,你用的是Tstrings,方法不是这里的主要问题,我想不明白的是你的a:PMyRecord;这个指针,你的例子里面只是使用了一次。我的根据数据记录要使用N次。我也试过只用一次New指针或者Create对象,然后赋值,然后添加到AList,结果是要么AList的所有内容同一 。如果我在需要用Alist之前释放了a指针,运行期错误:存取地址错。如果我逐一New指针或者Create对象,那么就不会有错误或问题,但是,我的列表里面指向了程序不可释放的地址。也就是说采用Diapose没有功效或者出错。

JavaD 2004-07-09
  • 打赏
  • 举报
回复
在你不用的时候dispose啊,循环你只要包含Flist.AddObject('xxx',a);
就好了
IFindit 2004-07-09
  • 打赏
  • 举报
回复
xyqxj(蓝泥) , 你用的是add方法, 应该是addobject方法,你再试试,我这没问题呀!
xyqxj 2004-07-09
  • 打赏
  • 举报
回复
请问什么时候dispose掉a啊。另外你的例子中没有包含循环啊,我的有循环的。
JavaD 2004-07-09
  • 打赏
  • 举报
回复
大概应该是这个样子,就不会有问题
type
pmyrecord = ^tmyrecord
tmyrecord = record
a:string;
end;

tmyclass = class
private
flist : TStringList;
procedure freeFlist;
end;

implementation

procedure freeFlist;
begin
while flist.Objects[0] <> nil then
begin
dispose(PMyRecord(fList.Objects[0]);
FList.delete(0);
end;
end;

程序中使用
var
a:PMyRecord;
begin
new(a);
Flist.AddObject('xxx',a);
....
end;
xyqxj 2004-07-09
  • 打赏
  • 举报
回复
晕!写错,

..打开数据..
while not eof do begin
AData:=Tobjectxx.create;
..赋值给AData..
Alist.Add(AData);
next;
end;
xyqxj 2004-07-09
  • 打赏
  • 举报
回复
我试过很多次,但是出错了!
不管是全局对象还是局部对象AData,都需要在循环里面创建
AData:=Tobjectxx.create;
..打开数据..
while not eof do begin
Alist.Add(AData);
next;
end;
然后在主调用的程序里:
AList:=TobjectList.create;
..调用..
AList.free;

我困惑的地方是create 了N 个AData却不能free掉。似乎唯一的解释是,AList.free是就把相应的AData释放了,因为他们是对象引用的关系。但是Adata是过程中的一个局部对象时,我就解释不过来了,按道理它的生存期已经结束,我的AList调用结束后,所指向的地方应该不存在正确的值了。但是我得到了正确的值!奇怪,就好像指针跑到程序外面的内存区块了一样。


yinzhiw 2004-07-08
  • 打赏
  • 举报
回复
我也想知道
到底addobject中增加的类或者指针类型的变量,做deleteObject之类的操作
是否学要释放那个变量,如果要的话怎么释放呢?
IFindit 2004-07-08
  • 打赏
  • 举报
回复
另外,在删除列表中的每一项时要free它开的那块内存(有的说是不用管,列表自己会释放,没有测试过,不能确定,if pointer <> nil then free 一下比较好!)
IFindit 2004-07-08
  • 打赏
  • 举报
回复
不是这样, 列表内部会搞一块内存,把你那个指针指向的内容取出来了,你可以在程序里试一下!
xyqxj 2004-07-08
  • 打赏
  • 举报
回复
谢谢两位!
但是如果我把AData定义为全局变量,并且只create一次,在AddObject时,他取得是一个指针值,并且指向的是Adata的指针地址,这样一个列表全部装了同一的地址。
我的理解是这样的,不知道对不对,还望深入指点!
IFindit 2004-07-08
  • 打赏
  • 举报
回复
问题说得有点模糊,但我已经明白:
1.你最好不要用局部对象(自己定义的那个类), 因为这里只是一个临时的对象,所以,用全局对象,这样就不用在循环中来回地create,free, 只需要在循环开始之前create, 循环后free,具体中间给它想付什么值就付就行了。
2.Alist.items.addobject()方法中的参数用( TObject(ainteger) ), 简洁,并且不需要,自己定义类,及create和free的问题,但是只能加一个整数,如果想在列表中加许多个值,那就只能自己定义类了,适你的应用而选择!
IFindit 2004-07-08
  • 打赏
  • 举报
回复
你是否在用局部对象时,调用了其CREATE方法,如果调用了,必须要FREE呀,如果没有CREATE,直接副值是不对的

16,743

社区成员

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

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