怎样释放嵌套tlist的集合内存(100分)

  • 主题发起人 主题发起人 it80
  • 开始时间 开始时间
I

it80

Unregistered / Unconfirmed
GUEST, unregistred user!
type
Pa=^Ta;
Ta=Record
a1:string[60]

a2:Tb;
a3:Tlist
//存放Pb型数据,数量不定
end;

Pb=^Tb
Tb=real;

Tc=class
private
public
aList:TList
//存放Pa型数据,数量不定
constructor Create
overload;
destructor Destroy
override;
procedure Free;
procedure Reflash;
procedure loadfile(const name: string);
procedure savefile;

end;

------
//在退出程序 时

i:=Tc.aList.Count;
if i>0 then
begin
for n:=0 to i-1 do
begin
m:=Pa(Tc.aList.Items[n]).a3.Count;
for j:=0 to m-1 do
begin
Dispose(Pa( Tc.aList.Items[n]).a3.Items[j])
end;
end;
// Dispose(Tc.aList.Items[n])
//会出错
end;
这样仅嵌套一次就存在内存泄漏,若更多嵌套(若pb是类似pa那样含有tlist)就更严重了,请各位帮忙整理一下
 
不知道你其它地方是如何处理的, 请试试行不行
i:=Tc.aList.Count;
if i>0 then
begin
for n:=0 to i-1 do
if Tc.aList.Items[n]<>nil then
begin
m:=Pa(Tc.aList.Items[n]).a3.Count;
for j:=0 to m-1 do
Dispose(Pa( Tc.aList.Items[n]).a3.Items[j]);
Dispose(Tc.aList.Items[n]);
end;
end;
 
还是有侧漏啊。。
 
一般是 从high downto Low 来释放。 先放到一个变量,然后删除节点, 然后释放变量,再循环下一个。
另外嵌套太多的话你应该简化,可能你的作法不够好。
 
实际工程中是从high到low的。。。跟这个没有关系。
主要问题是 pa.a3中的tlist中的对象被dispose后,pa.a1、pa.a2没有处理(理论上是系统会自己释放内存)
,如果dispose Tc.alist[n](pa)就会出错
 
不能用自释放类,如TObjectList么
 
一般使用TList保存对象列表,可以定义一个类来继承TList,如TPaList,然后重载它的Notify方法,Notify是在TList进行增加和删除时调用的一个虚方法,你在重载的代码里判断一下如果是delete则Dispose该指针对象即可。给你一个我写的例子吧:
我的TChannel是一个TObject派生出来的类,所以用FreeAndNil来释放,经过测试发现,使用FreeAndNil释放record的指针也是可以的,用Dispose释放TObject的派生类的实例也没问题,呵呵。
TChannelList = class(TList)
private
function GetItemByID(ChannelSerial: Integer): TChannel;
function GetItemByIndex(Index: Integer): TChannel;
protected
procedure Notify(Ptr: Pointer
Action: TListNotification)
override;
public
property Channels[Index : Integer] : TChannel read GetItemByIndex;
property LocateID[ChannelSerial : Integer] : TChannel read GetItemByID;
end;


function TChannelList.GetItemByID(ChannelSerial: Integer): TChannel;
var
i : Integer;
begin
Result := nil;
for i := 0 to Count - 1 do
begin
if (Channels.ChannelSerial = ChannelSerial) then
begin
Result := Channels;
Break;
end;
end;
end;

function TChannelList.GetItemByIndex(Index: Integer): TChannel;
begin
Result := TChannel(Items[Index]);
end;

procedure TChannelList.Notify(Ptr: Pointer
Action: TListNotification);
begin
if (Action = lnDeleted) then
FreeAndNil(Ptr);
inherited;
end;
 
谢楼上,试试看。。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
687
import
I
I
回复
0
查看
763
import
I
I
回复
0
查看
612
import
I
后退
顶部