问一个怪或不怪问题,对DELPHI编译了解的进来

边缘998 2009-03-29 10:33:27
大家都知道对象创建之后要FREE,这是个习惯.
如aLst:=TList.Create;
tmp:TXXX.Create;
aLst.add(tmp);
TXXX(aLst[0]).Free;
aLst.free;
正常,这个大家应该都没问题吧.
近日,我用ROMOBJ,和IO,我发现它的DAO机制,感觉有些不对,但我又解释不了,他的底层我猜想也是用LIST来添加对象.

它是这样的,
XXDAO:TXXXX类,类里面有个ADDITEM方法,用来添加对象的.

代码如下:
XXDAO:=TXXXX.Create;
for i:=1 to 2 do
begin
tmpSubDao:=TsubXXX.Create;
tmpSubDao.属性:=赋值;
XXDAO.ADDITEM(tmpSubDao);
tmpSubDao.free
end;
XXDAO.Free;


问题:同样在XP SP2下两台机测试,红色部分如果注释了,两台机执行XXDAO.FREE均没问题,但这样会有内存泄漏,但如果不注释
则有这样的反应,A机正常,B机在XXDAO.Free;时报错,错什么呢,提示地址出错.无语了,
我现在怀疑两台机装上DELPHI后,默认的编译指令不同导致内存检则不同.但又无从下手,望高手出招,替小弟干掉.


...全文
145 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
边缘998 2009-04-01
  • 打赏
  • 举报
回复
请看8楼,下面的朋友
A,B机装的是同一版本DELPHI,但在A机上可以进行两次FREE,而B机却不行.为什么.
try__again 2009-03-31
  • 打赏
  • 举报
回复
个人觉得不能free,理由同一楼
lhy 2009-03-31
  • 打赏
  • 举报
回复
在哪里编译的?
在A机编译完在B机运行什么结果?
在B机编译完在A机运行什么结果?
边缘998 2009-03-31
  • 打赏
  • 举报
回复
里面是创过一个新的实例对象。
我分别在A机和B机中试过这样的测试.

XXDAO:=TXXXX.Create;
for i:=1 to 2 do
begin
tmpSubDao:=TsubXXX.Create;
tmpSubDao.属性:=赋值;
XXDAO.ADDITEM(tmpSubDao);
// tmpSubDao.free
end;

//在这里将其子项FREE
for i:=XXDAO.itemcount-1 do
XXDAO.item[i].Free;

for i:=XXDAO.itemcount-1 do
XXDAO.item[i].Free;


XXDAO.Free;

注意红色部份。
A机中,连续这样两次FREE,正确。B机中,只执行前面一个FOR,全部FREE完了,再执行第二个FOR就执地址出错了。
我想B机应该是正确的,但我不明白为什么A机可以这样的FREE两次?这是什么原来,我只创建一次,
注意我把创建时的哪个tmpSubDao.free 注释了


高手说说。

Harryfin 2009-03-30
  • 打赏
  • 举报
回复
remobj和io都有源代码,你也不妨可以看看它底层是否有对这个对象进行声明周期管理
ljluck7687 2009-03-30
  • 打赏
  • 举报
回复
程序的写法应该没有问题,你不妨在有问题的机器上将项目的编译选项全部选中再试下
liangpei2008 2009-03-30
  • 打赏
  • 举报
回复
关键是要看ADDITEM如何实现的!(没用过RemObj,不过从管理对象的角度上看,应该是个容器,如:Collection,而单个对象可以从CollectionItem继承)
如用List的Add时,因为List中仅保存着tmp对象的栈引用,实体在堆中,如果你把堆对象给释放了,List中的对象指针肯定是无效的,放到哪都会出AV错误的
baseyueliang 2009-03-30
  • 打赏
  • 举报
回复
红色不能释放;
内存泄露是List在释放的时候,没有对Items中的每个对象Free
边缘998 2009-03-29
  • 打赏
  • 举报
回复
如果换我来写这个程序,我会把ADDITEM添加的对象放到XXDAO.FREE中去释放.这样比较好控制FREE
边缘998 2009-03-29
  • 打赏
  • 举报
回复
这个我也测试过,是的,如果我将tmpSubDao.Free执行了,哪么XXDAO.object[i]个对象里的属性值都没有了,
所以我认定是不能FREE,但怪就怪在,好多台机测试过了,
XXDAO:=TXXXX.Create;
for i:=1 to 2 do
begin
tmpSubDao:=TsubXXX.Create;
tmpSubDao.属性:=赋值;
XXDAO.ADDITEM(tmpSubDao);
tmpSubDao.free
end;
XXDAO.Free;

N台机正常
唯独一台机不正常
执行XXDAO.Free的时候就报空地址出错.
我想他的XXDAO在FREE的时候也会同时去处理ADD进去的对象的,不然就像僵哥你所说的野指针了.


但很多以机的DELPHI下调试都是带FREE正常,不解......
僵哥 2009-03-29
  • 打赏
  • 举报
回复
additem的目的是保存下来以备将来使用,所以你不能把它Free掉,一旦free掉,LIST当中保存的就是一个野指针,一个不仅没有任何价值,而且危害具大的野指针。

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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