内存释放问题。 ( 积分: 100 )

  • 主题发起人 主题发起人 abea
  • 开始时间 开始时间
A

abea

Unregistered / Unconfirmed
GUEST, unregistred user!
我在类中的成员函数返回一个TList,如下所示,然后再外面把它释放,可是释放时,老出错。请各位帮我看看。谢谢!

type
PMesItems = ^TMesItems

TMesItems = record
strItem : string
//²âÁ¿ÏîµÄ±êÌ&acirc

strID : Integer
//²¡È˵ÄID
strDateTime :string
//²âÁ¿Ê±¼&auml

end


//类中的内容
function TMesContrast.GetMuscleQuantityData: TList

var
tmpList:TList

tmpMesItems MesItems

begin
try
tmpList := TList.Create

if(NOt(dmMesContrast.qryFiveTee.Eof) and not(dmMesContrast.qryFiveTee.Bof )) then
begin
dmMesContrast.qryFiveTee.First

while(not(dmMesContrast.qryFiveTee.Eof)) do
begin
tmpMesItems := new(PMesItems)

tmpMesItems.strItemTitle := 'MuscleQuantity'

tmpMesItems.strLData := dmMesContrast.qryFiveTee.FieldByName('Lmf').AsString

tmpMesItems.strRData := dmMesContrast.qryFiveTee.FieldByName('Rmf').AsString

tmpMesItems.strID := dmMesContrast.qryFiveTee.FieldByName('CaseID').AsString

tmpMesItems.strDateTime := dmMesContrast.qryFiveTee.FieldByName('MeasureTime').AsString

tmpList.Add(tmpMesItems)

dmMesContrast.qryFiveTee.Next

end

dmMesContrast.qryFiveTee.First

end

result := tmpList

except
Result := nil

end

end


//外面的内容,去掉里面分配的内存。
procedure TMainForm.Button1Click(Sender: TObject)

var
objMes :TIMesContrast

tmpList:TList

tmpItemsMesItems

integer

strTmp:string

begin
strTmp := '1'

tmpList := Tlist.Create

objMes := TObjMesContrast.Create

objMes.SetPatientID(strTmp)

objMes.SetSQL('select * from mesc30 ')

tmpList := objMes.GetLegMuscleForceData

for i := 0 to tmplist.Count -1 do
begin
tmpItems := tmpList.items

dispose(tmpItems)

end


showmessage(IntToStr(tmpList.Count))

objMes.Free

tmpList.Free

end


//说明,我对c++比较在行,c++中可以用new分配内存,在外面释放没有问题。因为new是在堆中分配内存,只要指针存在,就可以释放。在delphi中可以么?如果我想把返回的tlist释放掉,应该怎么做?谢谢。
 
我在类中的成员函数返回一个TList,如下所示,然后再外面把它释放,可是释放时,老出错。请各位帮我看看。谢谢!

type
PMesItems = ^TMesItems

TMesItems = record
strItem : string
//²âÁ¿ÏîµÄ±êÌ&acirc

strID : Integer
//²¡È˵ÄID
strDateTime :string
//²âÁ¿Ê±¼&auml

end


//类中的内容
function TMesContrast.GetMuscleQuantityData: TList

var
tmpList:TList

tmpMesItems MesItems

begin
try
tmpList := TList.Create

if(NOt(dmMesContrast.qryFiveTee.Eof) and not(dmMesContrast.qryFiveTee.Bof )) then
begin
dmMesContrast.qryFiveTee.First

while(not(dmMesContrast.qryFiveTee.Eof)) do
begin
tmpMesItems := new(PMesItems)

tmpMesItems.strItemTitle := 'MuscleQuantity'

tmpMesItems.strLData := dmMesContrast.qryFiveTee.FieldByName('Lmf').AsString

tmpMesItems.strRData := dmMesContrast.qryFiveTee.FieldByName('Rmf').AsString

tmpMesItems.strID := dmMesContrast.qryFiveTee.FieldByName('CaseID').AsString

tmpMesItems.strDateTime := dmMesContrast.qryFiveTee.FieldByName('MeasureTime').AsString

tmpList.Add(tmpMesItems)

dmMesContrast.qryFiveTee.Next

end

dmMesContrast.qryFiveTee.First

end

result := tmpList

except
Result := nil

end

end


//外面的内容,去掉里面分配的内存。
procedure TMainForm.Button1Click(Sender: TObject)

var
objMes :TIMesContrast

tmpList:TList

tmpItemsMesItems

integer

strTmp:string

begin
strTmp := '1'

tmpList := Tlist.Create

objMes := TObjMesContrast.Create

objMes.SetPatientID(strTmp)

objMes.SetSQL('select * from mesc30 ')

tmpList := objMes.GetLegMuscleForceData

for i := 0 to tmplist.Count -1 do
begin
tmpItems := tmpList.items

dispose(tmpItems)

end


showmessage(IntToStr(tmpList.Count))

objMes.Free

tmpList.Free

end


//说明,我对c++比较在行,c++中可以用new分配内存,在外面释放没有问题。因为new是在堆中分配内存,只要指针存在,就可以释放。在delphi中可以么?如果我想把返回的tlist释放掉,应该怎么做?谢谢。
 
To abea: 你把tmplist.free换成freeandnil(tmplist)试试
 
procedure TMainForm.Button1Click(Sender: TObject)

var
objMes :TIMesContrast

tmpList:TList

tmpItemsMesItems

integer

strTmp:string

begin
strTmp := '1'

//tmpList := Tlist.Create
//此处不用创建
objMes := TObjMesContrast.Create

objMes.SetPatientID(strTmp)

objMes.SetSQL('select * from mesc30 ')

tmpList := objMes.GetLegMuscleForceData

for i := 0 to tmplist.Count -1 do
begin
tmpItems := tmpList.items

dispose(tmpItems)

end


showmessage(IntToStr(tmpList.Count))

objMes.Free

//tmpList.Free

freeandnil(tmplist);//改为这个试试
end

 
delphi中New是过程不是函数。
分配部分:
var
tmpMesItems: PMesItems


....
new(tmpMesItems);
tmpMesItems.strItemTitle := ....
....
tmpList.Add(tmpMesItems);

释放部分:
var
tmpMesItems: PMesItems;
begin
...
for i := 0 to tmpList.Count-1 do
begin
tmpMesItems := tmpList.Items;
dispose(tmpMesItems);
end;
...
tmpList.Free;
end;
 
改了还是不行。如果说用的是局部变量,不能够返回,可以我还能够取到list中的数据,但是释放内存的话,就出现错误。急急急啊。[:(!]
 
还有一种可能跟String类型有关,你试试:
type
PMesItems = ^TMesItems

TMesItems = record
strItem : string[255]
//²âÁ¿ÏîµÄ±êÌ&acirc

strID : Integer
//²¡È˵ÄID
strDateTime :string[255]
//²âÁ¿Ê±¼&auml

end;
 
把你的结构改一下:
type
PMesItems = ^TMesItems

TMesItems = record
strItem : widestring
//²âÁ¿ÏîµÄ±êÌ&acirc

strID : Integer
//²¡È˵ÄID
strDateTime :widestring
//²âÁ¿Ê±¼&auml

end


这样应该就好了
 
To abea: 请问您怎么知道,能够取到list中的数据?
 
to TYZhang,www, 我改了,还是不行。
to hylly,-- 我察看返回的list啊。就行了。
 
To abea: 'tmpItems := tmpList.items;'这句直接将指针赋给记录类型的变量?遍不过呀?
 
to hylly.可以的,没有问题。 tlist的items是一个指针类型的pointer,没有类型的。如果不放在类中处理。都没有问题。在一个函数中new 然后dispose是没有问题的。关键是我在dll的类中new,然后再外面dispose,可是,不行。
 
在dll中不可以。我的解决办法,在dll中再做个释放的函数,在exe中调用dll的释放函数来释放tmpList,不要在exe中释放dll中申请的内存。即那里申请那里释放。
 
procedure TMainForm.Button1Click(Sender: TObject)

var
objMes :TIMesContrast

tmpList:TList

tmpItemsMesItems

integer

strTmp:string

begin
strTmp := '1'

[red]tmpList := Tlist.Create
[/red] //该语句多余并且错误,将引起内存遗漏。(请删除)
objMes := TObjMesContrast.Create

objMes.SetPatientID(strTmp)

objMes.SetSQL('select * from mesc30 ')

[brown]tmpList := objMes.GetLegMuscleForceData
[/brown] //这个语句有可能返回空对象。
[red]if tmpList<>nil then[/red] //这儿必须做判断
for i := 0 to tmplist.Count -1 do
begin
tmpItems := tmpList.items

dispose(tmpItems)

end

objMes.Free

[red]if tmpList<>nil then[/red] //这儿必须做判断
tmpList.Free

end

按以上更改就不会出错了。
 
问题是,在释放内存的时候,基本上是在最后一个出现错误。前面的都没有问题。传出来的
list全部不为空,都有值,而且我验证了,全部正确,就是释放的时候会出现问题。是因为是在类的内部的原因么?
 
多人接受答案了。
 
后退
顶部